<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
    <meta name="keywords" content="imlgw,半岛铁盒,blog,Java博客,程序员,个人博客,java開發,程序員,個人博客,Java">
    <meta name="description" content="大悲无泪，大悟无言，大笑无声。">
    <meta name="author" content="Resolmi">
    
    <title>
        
            LeetCode滑动窗口 |
        
        Tadow
    </title>
    
<link rel="stylesheet" href="/css/style.css">

    <link rel="shortcut icon" href="https://static.imlgw.top/blog/20210731/BtJz541CcmJU.ico">
    <link rel="stylesheet" href="//cdn.jsdelivr.net/npm/hexo-theme-keep@3.4.3/source/css/font-awesome.min.css">
    <script id="hexo-configurations">
    let KEEP = window.KEEP || {};
    KEEP.hexo_config = {"hostname":"imlgw.top","root":"/","language":"zh-CN","path":"search.json"};
    KEEP.theme_config = {"toc":{"enable":true,"number":true,"expand_all":true,"init_open":true},"style":{"primary_color":"#0066CC","avatar":"https://static.imlgw.top/blog/20210731/3C7hCSRR3lfq.png","favicon":"https://static.imlgw.top/blog/20210731/BtJz541CcmJU.ico","article_img_align":"left","left_side_width":"260px","content_max_width":"920px","hover":{"shadow":false,"scale":true},"first_screen":{"enable":true,"background_img":"/images/image.svg","description":"Keep It Simple & Stupid."},"scroll":{"progress_bar":{"enable":true},"percent":{"enable":true}}},"local_search":{"enable":true,"preload":false},"code_copy":{"enable":true,"style":"default"},"pjax":{"enable":true},"lazyload":{"enable":true},"version":"3.4.3"};
    KEEP.language_ago = {"second":"%s 秒前","minute":"%s 分钟前","hour":"%s 小时前","day":"%s 天前","week":"%s 周前","month":"%s 月前","year":"%s 年前"};
  </script>
<meta name="generator" content="Hexo 5.4.0"><link rel="stylesheet" href="/css/prism.css" type="text/css"></head>


<body>
<div class="progress-bar-container">
    
        <span class="scroll-progress-bar"></span>
    

    
        <span class="pjax-progress-bar"></span>
        <span class="pjax-progress-icon">
            <i class="fas fa-circle-notch fa-spin"></i>
        </span>
    
</div>


<main class="page-container">

    

    <div class="page-main-content">

        <div class="page-main-content-top">
            <header class="header-wrapper">

    <div class="header-content">
        <div class="left">
            
            <a class="logo-title" href="/">
                Tadow
            </a>
        </div>

        <div class="right">
            <div class="pc">
                <ul class="menu-list">
                    
                        <li class="menu-item">
                            <a class=""
                               href="/"
                            >
                                首页
                            </a>
                        </li>
                    
                        <li class="menu-item">
                            <a class=""
                               href="/archives"
                            >
                                归档
                            </a>
                        </li>
                    
                        <li class="menu-item">
                            <a class=""
                               href="/categories"
                            >
                                分类
                            </a>
                        </li>
                    
                        <li class="menu-item">
                            <a class=""
                               href="/sbe"
                            >
                                订阅
                            </a>
                        </li>
                    
                        <li class="menu-item">
                            <a class=""
                               href="/links"
                            >
                                友链
                            </a>
                        </li>
                    
                        <li class="menu-item">
                            <a class=""
                               href="/about"
                            >
                                关于
                            </a>
                        </li>
                    
                    
                        <li class="menu-item search search-popup-trigger">
                            <i class="fas fa-search"></i>
                        </li>
                    
                </ul>
            </div>
            <div class="mobile">
                
                    <div class="icon-item search search-popup-trigger"><i class="fas fa-search"></i></div>
                
                <div class="icon-item menu-bar">
                    <div class="menu-bar-middle"></div>
                </div>
            </div>
        </div>
    </div>

    <div class="header-drawer">
        <ul class="drawer-menu-list">
            
                <li class="drawer-menu-item flex-center">
                    <a class=""
                       href="/">首页</a>
                </li>
            
                <li class="drawer-menu-item flex-center">
                    <a class=""
                       href="/archives">归档</a>
                </li>
            
                <li class="drawer-menu-item flex-center">
                    <a class=""
                       href="/categories">分类</a>
                </li>
            
                <li class="drawer-menu-item flex-center">
                    <a class=""
                       href="/sbe">订阅</a>
                </li>
            
                <li class="drawer-menu-item flex-center">
                    <a class=""
                       href="/links">友链</a>
                </li>
            
                <li class="drawer-menu-item flex-center">
                    <a class=""
                       href="/about">关于</a>
                </li>
            
        </ul>
    </div>

    <div class="window-mask"></div>

</header>


        </div>

        <div class="page-main-content-middle">

            <div class="main-content">

                
                    <div class="fade-in-down-animation">
    <div class="article-content-container">

        <div class="article-title">
            <span class="title-hover-animation">LeetCode滑动窗口</span>
        </div>

        
            <div class="article-header">
                <div class="avatar">
                    <img src="https://static.imlgw.top/blog/20210731/3C7hCSRR3lfq.png">
                </div>
                <div class="info">
                    <div class="author">
                        <span class="name">Resolmi</span>
                        
                            <span class="author-label">BOSS</span>
                        
                    </div>
                    <div class="meta-info">
                        <div class="article-meta-info">
    <span class="article-date article-meta-item">
        <i class="fas fa-edit"></i>&nbsp;2019-07-20 00:00:00
    </span>
    
        <span class="article-categories article-meta-item">
            <i class="fas fa-folder"></i>&nbsp;
            <ul>
                
                    <li>
                        <a href="/categories/%E7%AE%97%E6%B3%95/">算法</a>&nbsp;
                    </li>
                
            </ul>
        </span>
    
    
        <span class="article-tags article-meta-item">
            <i class="fas fa-tags"></i>&nbsp;
            <ul>
                
                    <li>
                        <a href="/tags/LeetCode/">LeetCode</a>&nbsp;
                    </li>
                
                    <li>
                        | <a href="/tags/%E6%BB%91%E5%8A%A8%E7%AA%97%E5%8F%A3/">滑动窗口</a>&nbsp;
                    </li>
                
            </ul>
        </span>
    

    
    
        <span class="article-wordcount article-meta-item">
            <i class="fas fa-file-word"></i>&nbsp;<span>21k 字</span>
        </span>
    
    
        <span class="article-min2read article-meta-item">
            <i class="fas fa-clock"></i>&nbsp;<span>96 分钟</span>
        </span>
    
    
        <span class="article-pv article-meta-item">
            <i class="fas fa-eye"></i>&nbsp;<span id="busuanzi_value_page_pv"></span>
        </span>
    
</div>

                    </div>
                </div>
            </div>
        

        <div class="article-content markdown-body">
            <h2 id="LeetCode-滑动窗口"><a href="#LeetCode-滑动窗口" class="headerlink" title="LeetCode 滑动窗口"></a>LeetCode 滑动窗口</h2><p>滑动问题包含一个滑动窗口，它是一个运行在一个大数组上的子列表，该数组是一个底层元素集合。假设有数组 [a b c d e f g h ]，一个大小为 3 的 <strong>滑动窗口</strong> 在其上滑动，则有：</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">[a b c]</span><br><span class="line">  [b c d]</span><br><span class="line">    [c d e]</span><br><span class="line">      [d e f]</span><br><span class="line">        [e f g]</span><br><span class="line">          [f g h]</span><br></pre></td></tr></table></figure>

<p>一般情况下就是使用这个窗口在数组的 <strong>合法区间</strong> 内进行滑动，同时 <strong>动态地</strong>记录一些有用的数据，很多情况下，能够极大地提高算法地效率。</p>
<h2 id="239-滑动窗口最大值"><a href="#239-滑动窗口最大值" class="headerlink" title="239. 滑动窗口最大值"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/sliding-window-maximum/" >239. 滑动窗口最大值<i class="fas fa-external-link-alt"></i></a></h2><p>给定一个数组 <em>nums</em>，有一个大小为 <em>k</em> 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口 <em>k</em> 内的数字。滑动窗口每次只向右移动一位。</p>
<p>返回滑动窗口最大值。</p>
<p><strong>示例:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入: nums = [<span class="number">1</span>,<span class="number">3</span>,-<span class="number">1</span>,-<span class="number">3</span>,<span class="number">5</span>,<span class="number">3</span>,<span class="number">6</span>,<span class="number">7</span>], 和 k = <span class="number">3</span></span><br><span class="line">输出: [<span class="number">3</span>,<span class="number">3</span>,<span class="number">5</span>,<span class="number">5</span>,<span class="number">6</span>,<span class="number">7</span>] </span><br><span class="line">解释: </span><br><span class="line"></span><br><span class="line">  滑动窗口的位置                最大值</span><br><span class="line">---------------               -----</span><br><span class="line">[<span class="number">1</span>  <span class="number">3</span>  -<span class="number">1</span>] -<span class="number">3</span>  <span class="number">5</span>  <span class="number">3</span>  <span class="number">6</span>  <span class="number">7</span>       <span class="number">3</span></span><br><span class="line"> <span class="number">1</span> [<span class="number">3</span>  -<span class="number">1</span>  -<span class="number">3</span>] <span class="number">5</span>  <span class="number">3</span>  <span class="number">6</span>  <span class="number">7</span>       <span class="number">3</span></span><br><span class="line"> <span class="number">1</span>  <span class="number">3</span> [-<span class="number">1</span>  -<span class="number">3</span>  <span class="number">5</span>] <span class="number">3</span>  <span class="number">6</span>  <span class="number">7</span>       <span class="number">5</span></span><br><span class="line"> <span class="number">1</span>  <span class="number">3</span>  -<span class="number">1</span> [-<span class="number">3</span>  <span class="number">5</span>  <span class="number">3</span>] <span class="number">6</span>  <span class="number">7</span>       <span class="number">5</span></span><br><span class="line"> <span class="number">1</span>  <span class="number">3</span>  -<span class="number">1</span>  -<span class="number">3</span> [<span class="number">5</span>  <span class="number">3</span>  <span class="number">6</span>] <span class="number">7</span>       <span class="number">6</span></span><br><span class="line"> <span class="number">1</span>  <span class="number">3</span>  -<span class="number">1</span>  -<span class="number">3</span>  <span class="number">5</span> [<span class="number">3</span>  <span class="number">6</span>  <span class="number">7</span>]      <span class="number">7</span></span><br></pre></td></tr></table></figure>

<p><strong>注意：</strong></p>
<p>你可以假设 <em>k</em> 总是有效的，1 ≤ k ≤ 输入数组的大小，且输入数组不为空。</p>
<p><strong>进阶：</strong></p>
<p>你能在线性时间复杂度内解决此题吗？</p>
<p><strong>解法一</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">int</span>[] maxSlidingWindow2(<span class="keyword">int</span>[] nums, <span class="keyword">int</span> k) &#123;</span><br><span class="line">    <span class="comment">//题目上说的不为空，还是给我来了个空。。。。</span></span><br><span class="line">    <span class="keyword">if</span>(nums.length==<span class="number">0</span>)&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">new</span> <span class="keyword">int</span>[]&#123;&#125;;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span>(k==<span class="number">1</span>) <span class="keyword">return</span> nums;</span><br><span class="line">    LinkedList&lt;Integer&gt; list=<span class="keyword">new</span> LinkedList&lt;Integer&gt;();</span><br><span class="line">    <span class="keyword">int</span> []res=<span class="keyword">new</span> <span class="keyword">int</span>[nums.length-k+<span class="number">1</span>];</span><br><span class="line">    <span class="keyword">int</span> index=<span class="number">0</span>;</span><br><span class="line">    list.add(<span class="number">0</span>);</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i=<span class="number">1</span>;i&lt;nums.length;i++) &#123;</span><br><span class="line">        <span class="keyword">while</span>(!list.isEmpty() &amp;&amp; nums[list.getLast()]&lt;nums[i])&#123;</span><br><span class="line">            <span class="comment">//小于nums[i]的元素,从右边(尾)出队列 ,控制最左边(头)最大</span></span><br><span class="line">            list.removeLast();</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="comment">//然后将它加到队列中，从右边(尾)</span></span><br><span class="line">        list.addLast(i);</span><br><span class="line">        <span class="comment">//如果队列溢出了就从右边移除一个（头）</span></span><br><span class="line">        <span class="keyword">if</span>(i-list.getFirst()==k)&#123;</span><br><span class="line">            list.removeFirst();</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span>(i&gt;=k-<span class="number">1</span>)&#123;</span><br><span class="line">            res[index++]=nums[list.getFirst()];</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<blockquote>
<p>2020.2.9 回头看了下，这不是单调队列么😂（用堆也可以啦，不过既然要在头尾都操作，直接用队列会更方便）</p>
</blockquote>
<p>其实开始我也不会做，看了提示后搞了半天才弄出来，23ms，70%左右，思路就是利用一个双端队列(头尾都可以进出)，队列中存<strong>数组下标</strong>，然后遍历数组，在进入队列时从右向左遍历队尾，将<strong>小于当前元素</strong>的队尾元素去除(因为已经没用了，后面的最大值不可能是它们)，举个例子</p>
<blockquote>
<p>[2，1，-1，3，……]  k=3 ，当读到<strong>3</strong>这个元素的时候，窗口再向右移动最大值肯定不会是右边的元素了，所以直接剔除他们，在纸上画一画就明白了</p>
</blockquote>
<p>然后很关键的一步就是什么时候移除最左边的元素，其实按照人的思路来想就是最左边的元素不在窗口内的时候，比如上面的例子，读到<strong>3</strong>的时候，<strong>2</strong>其实就应该剔除了因为它已经不在窗口内了。用代码来描述就是</p>
<p><code>i-list.getFirst()==k</code>，i代表<strong>当前元素下标</strong>，上面的例子<strong>3</strong>对应的<strong>i</strong>就是<strong>3</strong>，<strong>list.getFirst()=0</strong>，刚好差为k，就代表<strong>2</strong>已经超出窗口了应该移除了。</p>
<p>其实这里我开始不是这样做的，我在队列里面存的不是元素索引，我存的是元素，然后在判断什么时候移除的时候发现判断不了，<strong>index</strong>也只是结果元素的下标，并不能代表队列最左元素的下标，对于数组存下标优先于存元素，多一个已知量有时候还是很方便的</p>
<p><strong>解法二</strong></p>
<p>属于对暴力法的优化吧，最坏情况下时间复杂度<code>O(NK)</code>，比如完全逆序的情况（2020.2.9回顾fix）</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">int</span>[] maxSlidingWindow3(<span class="keyword">int</span>[] nums, <span class="keyword">int</span> k) &#123;</span><br><span class="line">    <span class="comment">//题目上说的不为空，还是给我来了个空。。。。</span></span><br><span class="line">    <span class="keyword">int</span> len = nums.length;</span><br><span class="line">    <span class="keyword">if</span> (len == <span class="number">0</span>) <span class="keyword">return</span> <span class="keyword">new</span> <span class="keyword">int</span>[]&#123;&#125;;</span><br><span class="line">    <span class="keyword">if</span> (len == <span class="number">1</span>) <span class="keyword">return</span> <span class="keyword">new</span> <span class="keyword">int</span>[]&#123;nums[<span class="number">0</span>]&#125;;</span><br><span class="line">    <span class="keyword">int</span> localMax = Integer.MIN_VALUE;</span><br><span class="line">    <span class="keyword">int</span>[] result = <span class="keyword">new</span> <span class="keyword">int</span>[len - k + <span class="number">1</span>];</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; k; i++) &#123;</span><br><span class="line">        <span class="comment">//找到第一个窗口的最大值</span></span><br><span class="line">        localMax = max(nums[i], localMax);</span><br><span class="line">    &#125;</span><br><span class="line">    result[<span class="number">0</span>] = localMax;</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">1</span>; i &lt; len - k + <span class="number">1</span>; i++) &#123;</span><br><span class="line">        <span class="comment">//窗口的下一个元素 k=3 , i=1 下一个元素下标为 3</span></span><br><span class="line">        <span class="keyword">if</span> (nums[i + k - <span class="number">1</span>] &gt; localMax) &#123;</span><br><span class="line">            <span class="comment">//判断当前窗口最大值和下一个元素的大小</span></span><br><span class="line">            <span class="comment">//如果比当前窗口的最大值还要大 就不用找了 就是它了</span></span><br><span class="line">            localMax = nums[i + k - <span class="number">1</span>];</span><br><span class="line">        &#125; <span class="keyword">else</span> <span class="keyword">if</span> (nums[i - <span class="number">1</span>] == localMax) &#123;</span><br><span class="line">            <span class="comment">//下一个元素比当前窗口最大值小 而且很不巧</span></span><br><span class="line">            <span class="comment">//当前最大值刚好是当前窗口的最左边的元素，也就是马上要超过窗口的元素</span></span><br><span class="line">            localMax = nums[i];</span><br><span class="line">            <span class="comment">//所以就要重新找最大值</span></span><br><span class="line">            <span class="keyword">for</span> (<span class="keyword">int</span> x = i; x &lt; i + k; x++) &#123;</span><br><span class="line">                localMax = max(nums[x], localMax);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="comment">//剩下的请况就是 比当前最大值小，并且最大值不是最左边的元素(还没有出界)，最大值不变</span></span><br><span class="line">        <span class="comment">//copy到结果中</span></span><br><span class="line">        result[i] = localMax;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> result;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//其实可以用Math.max()</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">int</span> <span class="title">max</span><span class="params">(<span class="keyword">int</span> a,<span class="keyword">int</span> b)</span></span>&#123;</span><br><span class="line">    <span class="keyword">if</span>(a&gt;=b)<span class="keyword">return</span> a;</span><br><span class="line">    <span class="keyword">return</span> b;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>2ms，99%  提交记录这种做法是最快的😂，时间复杂度最坏应该是<code>O(NK)</code></p>
<h2 id="5312-大小为-K-且平均值大于等于阈值的子数组数目"><a href="#5312-大小为-K-且平均值大于等于阈值的子数组数目" class="headerlink" title="5312. 大小为 K 且平均值大于等于阈值的子数组数目"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/number-of-sub-arrays-of-size-k-and-average-greater-than-or-equal-to-threshold/" >5312. 大小为 K 且平均值大于等于阈值的子数组数目<i class="fas fa-external-link-alt"></i></a></h2><p>给你一个整数数组 <code>arr</code> 和两个整数 <code>k</code> 和 <code>threshold</code> 。</p>
<p>请你返回长度为 <code>k</code> 且平均值大于等于 <code>threshold</code> 的子数组数目。</p>
<p> <strong>示例 1：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入：arr = [<span class="number">2</span>,<span class="number">2</span>,<span class="number">2</span>,<span class="number">2</span>,<span class="number">5</span>,<span class="number">5</span>,<span class="number">5</span>,<span class="number">8</span>], k = <span class="number">3</span>, threshold = <span class="number">4</span></span><br><span class="line">输出：<span class="number">3</span></span><br><span class="line">解释：子数组 [<span class="number">2</span>,<span class="number">5</span>,<span class="number">5</span>],[<span class="number">5</span>,<span class="number">5</span>,<span class="number">5</span>] 和 [<span class="number">5</span>,<span class="number">5</span>,<span class="number">8</span>] 的平均值分别为 <span class="number">4</span>，<span class="number">5</span> 和 <span class="number">6</span> 。其他长度为 <span class="number">3</span> 的子数组的平均值都小于 <span class="number">4</span> （threshold 的值)。</span><br></pre></td></tr></table></figure>


<p><strong>示例 2：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入：arr = [<span class="number">1</span>,<span class="number">1</span>,<span class="number">1</span>,<span class="number">1</span>,<span class="number">1</span>], k = <span class="number">1</span>, threshold = <span class="number">0</span></span><br><span class="line">输出：<span class="number">5</span></span><br></pre></td></tr></table></figure>


<p><strong>示例 3：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入：arr = [<span class="number">11</span>,<span class="number">13</span>,<span class="number">17</span>,<span class="number">23</span>,<span class="number">29</span>,<span class="number">31</span>,<span class="number">7</span>,<span class="number">5</span>,<span class="number">2</span>,<span class="number">3</span>], k = <span class="number">3</span>, threshold = <span class="number">5</span></span><br><span class="line">输出：<span class="number">6</span></span><br><span class="line">解释：前 <span class="number">6</span> 个长度为 <span class="number">3</span> 的子数组平均值都大于 <span class="number">5</span> 。注意平均值不是整数。</span><br></pre></td></tr></table></figure>


<p><strong>示例 4：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入：arr = [<span class="number">7</span>,<span class="number">7</span>,<span class="number">7</span>,<span class="number">7</span>,<span class="number">7</span>,<span class="number">7</span>,<span class="number">7</span>], k = <span class="number">7</span>, threshold = <span class="number">7</span></span><br><span class="line">输出：<span class="number">1</span></span><br></pre></td></tr></table></figure>


<p><strong>示例 5：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入：arr = [<span class="number">4</span>,<span class="number">4</span>,<span class="number">4</span>,<span class="number">4</span>], k = <span class="number">4</span>, threshold = <span class="number">1</span></span><br><span class="line">输出：<span class="number">1</span></span><br></pre></td></tr></table></figure>

<p><strong>提示：</strong></p>
<ul>
<li><code>1 &lt;= arr.length &lt;= 10^5</code></li>
<li><code>1 &lt;= arr[i] &lt;= 10^4</code></li>
<li><code>1 &lt;= k &lt;= arr.length</code></li>
<li><code>0 &lt;= threshold &lt;= 10^4</code></li>
</ul>
<p><strong>解法一</strong></p>
<p>19双周赛的第2题，很简单的滑动窗口，枚举所有窗口计数就行了</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">numOfSubarrays</span><span class="params">(<span class="keyword">int</span>[] arr, <span class="keyword">int</span> k, <span class="keyword">int</span> threshold)</span> </span>&#123;</span><br><span class="line">    threshold*=k;</span><br><span class="line">    <span class="keyword">int</span> sum=<span class="number">0</span>;</span><br><span class="line">    <span class="keyword">int</span> count=<span class="number">0</span>;</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;k;i++) &#123;</span><br><span class="line">        sum+=arr[i];</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i=k;i&lt;arr.length;i++) &#123;</span><br><span class="line">        <span class="keyword">if</span> (sum&gt;=threshold) &#123;</span><br><span class="line">            count++;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="comment">//0 1 2 3</span></span><br><span class="line">        sum+=arr[i];</span><br><span class="line">        sum-=arr[i-k];</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> count;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="3-无重复字符的最长子串"><a href="#3-无重复字符的最长子串" class="headerlink" title="3. 无重复字符的最长子串"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/longest-substring-without-repeating-characters/" >3. 无重复字符的最长子串<i class="fas fa-external-link-alt"></i></a></h2><p>给定一个字符串，请你找出其中不含有重复字符的 <strong>最长子串</strong> 的长度。</p>
<p><strong>示例 1:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入: <span class="string">&quot;abcabcbb&quot;</span></span><br><span class="line">输出: <span class="number">3</span> </span><br><span class="line">解释: 因为无重复字符的最长子串是 <span class="string">&quot;abc&quot;</span>，所以其长度为 <span class="number">3</span>。</span><br></pre></td></tr></table></figure>

<p><strong>示例 2:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入: <span class="string">&quot;bbbbb&quot;</span></span><br><span class="line">输出: <span class="number">1</span></span><br><span class="line">解释: 因为无重复字符的最长子串是 <span class="string">&quot;b&quot;</span>，所以其长度为 <span class="number">1</span>。</span><br></pre></td></tr></table></figure>

<p><strong>示例 3:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入: <span class="string">&quot;pwwkew&quot;</span></span><br><span class="line">输出: <span class="number">3</span></span><br><span class="line">解释: 因为无重复字符的最长子串是 <span class="string">&quot;wke&quot;</span>，所以其长度为 <span class="number">3</span>。</span><br><span class="line">     请注意，你的答案必须是 子串 的长度，<span class="string">&quot;pwke&quot;</span> 是一个子序列，不是子串。</span><br></pre></td></tr></table></figure>

<p><strong>解法一</strong></p>
<p>这题其实很久以前(半年前)做过一次，当时用的方法很low😂</p>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="http://static.imlgw.top///20190503/zQ9MBrOhQm4S.png?imageslim"
                      alt="mark"
                ></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">lengthOfLongestSubstring</span><span class="params">(String s)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">char</span> [] chars = s.toCharArray();</span><br><span class="line">    <span class="keyword">if</span> (chars.length == <span class="number">0</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">int</span> length = <span class="number">1</span>;</span><br><span class="line">    String temp=<span class="keyword">new</span> String();</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i &lt;s.length()-<span class="number">1</span>; i++) &#123;</span><br><span class="line">        <span class="keyword">if</span>(chars[i] != chars[i+<span class="number">1</span>]) &#123;</span><br><span class="line">            temp=s.substring(i, i+<span class="number">2</span>);</span><br><span class="line">        &#125; <span class="keyword">else</span> <span class="keyword">continue</span>;</span><br><span class="line">        <span class="keyword">for</span> (<span class="keyword">int</span> j = i+<span class="number">2</span>; j &lt; s.length(); j++) &#123;</span><br><span class="line">            <span class="keyword">if</span> (!temp.contains(chars[j]+<span class="string">&quot;&quot;</span>)) &#123;</span><br><span class="line">                temp = s.substring(i, j+<span class="number">1</span>);</span><br><span class="line">            &#125; <span class="keyword">else</span> <span class="keyword">break</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="comment">//Break出来后判断是否是最长的k</span></span><br><span class="line">        length=temp.length()&gt;length?temp.length():length;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> length;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>我这种完全就是利用api暴力法，居然还跑过了，时间复杂度应该是O(N3)，这题的ac率还是挺低的只有 29.3%</p>
<p><strong>解法二</strong></p>
<p>下面的是我下午重新做的</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">int</span> <span class="title">lengthOfLongestSubstring4</span><span class="params">(String s)</span> </span>&#123;</span><br><span class="line">    <span class="comment">//边界问题永远不能忽略</span></span><br><span class="line">    <span class="comment">//LinkedList&lt;Integer&gt; list=new LinkedList&lt;&gt;();</span></span><br><span class="line">    <span class="keyword">int</span> length=s.length();</span><br><span class="line">    <span class="keyword">if</span>(length==<span class="number">0</span>) <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">int</span> head=<span class="number">0</span>,tail=<span class="number">0</span>;</span><br><span class="line">    <span class="keyword">int</span> max=<span class="number">1</span>;</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i=<span class="number">1</span>;i&lt;length;i++) &#123;</span><br><span class="line">        <span class="keyword">int</span> index=i-<span class="number">1</span>; <span class="comment">//当前元素前一个元素下标</span></span><br><span class="line">        <span class="keyword">while</span>(index&gt;=head)&#123;</span><br><span class="line">            <span class="keyword">if</span>(s.charAt(i)!=s.charAt(index))&#123;</span><br><span class="line">                index--;</span><br><span class="line">            &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">                <span class="comment">//按思路应该是把相等前所有元素移除，但是那样效率好低，所以这里我决定用数组模拟队列</span></span><br><span class="line">                head=index+<span class="number">1</span>;</span><br><span class="line">                tail++;</span><br><span class="line">                <span class="keyword">break</span>;</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="comment">//从尾遍历到头仍然没有相等，可以添加到队列中</span></span><br><span class="line">            <span class="keyword">if</span>(index==head-<span class="number">1</span>)&#123;</span><br><span class="line">                tail++;</span><br><span class="line">                <span class="keyword">break</span>;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="comment">//每次结束循环后 尾index-头index</span></span><br><span class="line">        max=tail-head+<span class="number">1</span> &gt; max?tail-head+<span class="number">1</span>:max;</span><br><span class="line">        <span class="comment">//System.out.println(max);</span></span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> max;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>20ms左右80%左右，思路也比较清晰，遍历字符串，然后从后往前遍历字符串，判断当前字符串在前面有没有，有的话就将前面相等那个元素(index)前的元素都移除（窗口右移）</p>
<p>eg: <code>[head...index....tail] i</code>  向右移动<code>....index [head ... i]</code></p>
<p>把当前元素添加进来，时间复杂度是O(N^2)，比上面单纯的暴力法要快多了，但是并不是最优解</p>
<p><strong>解法三</strong></p>
<p>上面的算法，其实还可以优化，每次判断前面有没有重复元素的时候可以直接用一个大小256的扩展ASCII码表数组来判断（前提是这些字符都在标准的ASCII字符中），<code>freq[s.charAt(i)]</code> 代表的就是s.charAt(i)这个字符在窗口内出现过没有，出现过就为1，否则就是0，这里如果ASCII不够其实也可以用HashMap，查找效率也很高接近O(1)</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">lengthOfLongestSubstring</span><span class="params">(String s)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">int</span> length=s.length();</span><br><span class="line">    <span class="keyword">if</span>(length==<span class="number">0</span>) <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">int</span>[] freq=<span class="keyword">new</span> <span class="keyword">int</span>[<span class="number">256</span>]; <span class="comment">//ASCII码表</span></span><br><span class="line">    freq[s.charAt(<span class="number">0</span>)]=<span class="number">1</span>;</span><br><span class="line">    <span class="keyword">int</span> head=<span class="number">0</span>,tail=<span class="number">0</span>;</span><br><span class="line">    <span class="keyword">int</span> max=<span class="number">1</span>;</span><br><span class="line">    <span class="keyword">while</span>(head&lt;length)&#123;</span><br><span class="line">        <span class="keyword">if</span>(tail+<span class="number">1</span>&lt;length&amp;&amp;freq[s.charAt(tail+<span class="number">1</span>)]==<span class="number">0</span>)&#123;</span><br><span class="line">            <span class="comment">//没有重复，右边界右移</span></span><br><span class="line">            tail++;</span><br><span class="line">            freq[s.charAt(tail)]++;</span><br><span class="line">        &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">            <span class="comment">//逐渐缩减左边界，直到不再有重复元素</span></span><br><span class="line">            freq[s.charAt(head)]--;</span><br><span class="line">            head++;</span><br><span class="line">        &#125;</span><br><span class="line">        max=max&lt;tail-head+<span class="number">1</span>?tail-head+<span class="number">1</span>:max;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> max;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>这种做法最坏情况（没有重复的字符）下其实会遍历两遍数组tail先移动到尾部head随后有移动到尾部，但是比较好理解，解法四实际上就是对这里的优化，head每次移动都是直接移动到上一个重复元素的位置，而不是一个一个的向右移</p>
<p><strong>解法四</strong></p>
<p>提交记录上最快的方法，理解起来有点费劲，现在回头看又看不懂了。。。</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">lengthOfLongestSubstring</span><span class="params">(String s)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">int</span> n = s.length(), ans = <span class="number">0</span>;</span><br><span class="line">    <span class="comment">//索引为元素值，这里因为元素都是字符转过来就是askll码，所以可以直接这样</span></span><br><span class="line">    <span class="keyword">int</span>[] index = <span class="keyword">new</span> <span class="keyword">int</span>[<span class="number">128</span>];</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> j = <span class="number">0</span>, i = <span class="number">0</span>; j &lt; n; j++) &#123;</span><br><span class="line">        <span class="comment">//如果字符 char 在没有出现过，index[char]为0，出现则index[char]是遍历出现的最后的char的位置</span></span><br><span class="line">        <span class="comment">// index[s.charAt(j)] 是当前字符上一次出现的位置(从1开始)</span></span><br><span class="line">        i = Math.max(i,index[s.charAt(j)]);</span><br><span class="line">        <span class="comment">//j - i + 1 就是舍弃s.charAt(j)重复出现之前字符的长度  如abca,当s.charAt(j) == a时，j - i + 1就是bca的长度</span></span><br><span class="line">        <span class="comment">//求最大值常规操作</span></span><br><span class="line">        ans = Math.max(ans, j - i + <span class="number">1</span>);</span><br><span class="line">        index[s.charAt(j)] = j + <span class="number">1</span>;</span><br><span class="line">        <span class="comment">// 从1开始</span></span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> ans;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>这里最主要就是这个<strong>i</strong>的理解</p>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="http://static.imlgw.top///20190503/Qcj2l3E0v5sN.png?imageslim"
                      alt="mark"
                ></p>
<p>这个i不一定是当前元素上一次出现的位置，也有可能是离<strong>当前</strong>元素从右向左<strong>最近</strong>的<strong>重复字符</strong>的_位置_。而index中存的就是这个元素的索引位置+1，为什么要加1？</p>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="http://static.imlgw.top///20190503/N4GzYaft0suh.png?imageslim"
                      alt="mark"
                ></p>
<p>主要是因为i的默认值是0而数组默认值也是0，如果以0开始就会出现上面的情况。</p>
<p>其实这两种算法也比较类似，只是后面判断字符是否出现过的方式不同，前者是直接遍历这个子串，后者是利用字符为索引，其值就是上一次出现的位置(+1)，借此来计算长度。</p>
<p><strong>回首掏</strong></p>
<p>19/9/14，在网页上又写了一种不同的解法，属于解法4的变体（做的时候并没有想到解法4），<code>freq[]</code> 数组索引是字符串，但是值是该字符在s中对应的索引，不会遍历两遍数组，left可以通过索引直接跳到上一次出现的位置</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">int</span> <span class="title">lengthOfLongestSubstring6</span><span class="params">(String s)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span>(s==<span class="keyword">null</span>||s.length()&lt;<span class="number">1</span>) <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">if</span>(s.length()==<span class="number">1</span>) <span class="keyword">return</span> <span class="number">1</span>;</span><br><span class="line">    <span class="keyword">int</span>[] freq=<span class="keyword">new</span> <span class="keyword">int</span>[<span class="number">256</span>];</span><br><span class="line">    <span class="keyword">int</span> left=<span class="number">0</span>,right=<span class="number">0</span>,res=<span class="number">0</span>;</span><br><span class="line">    Arrays.fill(freq,-<span class="number">1</span>);</span><br><span class="line">    <span class="keyword">while</span>(right&lt;s.length())&#123;</span><br><span class="line">        <span class="keyword">char</span> sr=s.charAt(right);</span><br><span class="line">        <span class="comment">//已经存在,并且在窗口内</span></span><br><span class="line">        <span class="keyword">if</span>(freq[sr]!=-<span class="number">1</span> &amp;&amp; freq[sr]&gt;=left)&#123;</span><br><span class="line">            <span class="comment">//System.out.println(left+&quot;,&quot;+right+&quot;,&quot;+freq[sr]);</span></span><br><span class="line">            res=Math.max(res,right-left);</span><br><span class="line">            left=freq[sr]+<span class="number">1</span>;</span><br><span class="line">            freq[sr]=right;</span><br><span class="line">        &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">            res=Math.max(res,right-left+<span class="number">1</span>);</span><br><span class="line">            freq[sr]=right;</span><br><span class="line">        &#125;</span><br><span class="line">        right++;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p><strong>回首掏2</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">int</span> <span class="title">lengthOfLongestSubstring7</span><span class="params">(String s)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span>(s==<span class="keyword">null</span>||s.length()&lt;<span class="number">1</span>) <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">if</span>(s.length()==<span class="number">1</span>) <span class="keyword">return</span> <span class="number">1</span>;</span><br><span class="line">    <span class="keyword">int</span>[] freq=<span class="keyword">new</span> <span class="keyword">int</span>[<span class="number">256</span>];</span><br><span class="line">    <span class="keyword">int</span> left=<span class="number">0</span>,right=<span class="number">0</span>,res=<span class="number">0</span>;</span><br><span class="line">    <span class="comment">//Arrays.fill(freq,-1);</span></span><br><span class="line">    <span class="keyword">while</span>(right&lt;s.length())&#123;</span><br><span class="line">        <span class="keyword">char</span> sr=s.charAt(right);</span><br><span class="line">        <span class="comment">//已经存在(出现过),并且上一次出现在窗口内</span></span><br><span class="line">        <span class="keyword">if</span>(freq[sr]!=<span class="number">0</span> &amp;&amp; freq[sr]&gt;=left)&#123;</span><br><span class="line">            <span class="comment">//这里不包含right,所以不用加1</span></span><br><span class="line">            res=Math.max(res,right-left);</span><br><span class="line">            <span class="comment">//left移动到重复位置元素的下一个</span></span><br><span class="line">            <span class="comment">//因为freq的值是存的索引+1所以这里不用+1</span></span><br><span class="line">            left=freq[sr];</span><br><span class="line">        &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">            <span class="comment">//这里包含right所以需要加1</span></span><br><span class="line">            res=Math.max(res,right-left+<span class="number">1</span>);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="comment">//加1是为了区别s的第一个字符</span></span><br><span class="line">        freq[sr]=right+<span class="number">1</span>;</span><br><span class="line">        right++;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>感觉对这题有很深的执念😅，对上面右优化了一下，但是其实还是上面的解法三比较简单，说到解法三，我又抽风改了一个boolean数组版本的</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">//update: 2020.4.13 重写了一遍，代码更简洁了</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">lengthOfLongestSubstring</span><span class="params">(String s)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span>(s==<span class="keyword">null</span> ||s.length()&lt;=<span class="number">0</span>) <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">boolean</span>[] freq=<span class="keyword">new</span> <span class="keyword">boolean</span>[<span class="number">128</span>];</span><br><span class="line">    <span class="keyword">int</span> left=<span class="number">0</span>,right=<span class="number">0</span>;</span><br><span class="line">    <span class="keyword">int</span> max=<span class="number">0</span>;</span><br><span class="line">    <span class="keyword">while</span>(left&lt;=right &amp;&amp; right&lt;s.length())&#123;</span><br><span class="line">        <span class="keyword">if</span>(!freq[s.charAt(right)])&#123;</span><br><span class="line">            max=Math.max(max,right-left+<span class="number">1</span>);</span><br><span class="line">            freq[s.charAt(right++)]=<span class="keyword">true</span>;</span><br><span class="line">        &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">            freq[s.charAt(left++)]=<span class="keyword">false</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> max;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p><strong><em>以上解法全部作废</em></strong></p>
<p>统一使用<code>for-while</code>结构，能用<code>for-if</code>的一定可以用<code>for-while</code>，反过来就不行</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">//2020.5.5根据自己总结的滑窗模板重写</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">lengthOfLongestSubstring</span><span class="params">(String s)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span>(s==<span class="keyword">null</span> || s.length()&lt;=<span class="number">0</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">int</span> n=s.length();</span><br><span class="line">    <span class="keyword">int</span> left=<span class="number">0</span>;</span><br><span class="line">    <span class="keyword">int</span> res=<span class="number">1</span>;</span><br><span class="line">    <span class="keyword">boolean</span>[] freq=<span class="keyword">new</span> <span class="keyword">boolean</span>[<span class="number">128</span>];</span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">int</span> right=<span class="number">0</span>;right&lt;n;right++)&#123;</span><br><span class="line">        <span class="keyword">while</span>(freq[s.charAt(right)])&#123;</span><br><span class="line">            freq[s.charAt(left++)]=<span class="keyword">false</span>; <span class="comment">//left不用限制</span></span><br><span class="line">        &#125;</span><br><span class="line">        freq[s.charAt(right)]=<span class="keyword">true</span>;</span><br><span class="line">        res=Math.max(res,right-left+<span class="number">1</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p><strong>最优解</strong></p>
<p>map记录元素最后出现的位置，当重复的时候更新起点，只用遍历一遍</p>
<figure class="highlight go"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">lengthOfLongestSubstring</span><span class="params">(s <span class="keyword">string</span>)</span> <span class="title">int</span></span> &#123;</span><br><span class="line">    <span class="keyword">if</span> <span class="built_in">len</span>(s)==<span class="number">0</span>&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="number">0</span></span><br><span class="line">    &#125;</span><br><span class="line">    m:=<span class="built_in">make</span>(<span class="keyword">map</span>[<span class="keyword">rune</span>]<span class="keyword">int</span>)</span><br><span class="line">    start:=<span class="number">0</span></span><br><span class="line">    res:=<span class="number">0</span></span><br><span class="line">    <span class="keyword">for</span> i,ch:=<span class="keyword">range</span> s&#123;</span><br><span class="line">        <span class="keyword">if</span> idx,ok:=m[ch];ok &amp;&amp; idx+<span class="number">1</span>&gt;start&#123;</span><br><span class="line">            start=idx+<span class="number">1</span></span><br><span class="line">        &#125;</span><br><span class="line">        m[ch]=i</span><br><span class="line">        res=Max(res,i-start+<span class="number">1</span>)</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> res</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">Max</span><span class="params">(a,b <span class="keyword">int</span>)</span> <span class="title">int</span></span>&#123;</span><br><span class="line">    <span class="keyword">if</span> a&gt;b&#123;</span><br><span class="line">        <span class="keyword">return</span> a</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> b</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="219-存在重复元素-II"><a href="#219-存在重复元素-II" class="headerlink" title="219. 存在重复元素 II"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/contains-duplicate-ii/" >219. 存在重复元素 II<i class="fas fa-external-link-alt"></i></a></h2><p>给定一个整数数组和一个整数 <em>k</em>，判断数组中是否存在两个不同的索引 <em>i</em> 和 <em>j</em>，使得 **nums [i] = nums [j]**，并且 <em>i</em> 和 <em>j</em> 的差的绝对值最大(不超过)为 <em>k</em>。</p>
<p><strong>示例 1:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入: nums = [<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">1</span>], k = <span class="number">3</span></span><br><span class="line">输出: <span class="keyword">true</span></span><br></pre></td></tr></table></figure>

<p><strong>示例 2:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入: nums = [<span class="number">1</span>,<span class="number">0</span>,<span class="number">1</span>,<span class="number">1</span>], k = <span class="number">1</span></span><br><span class="line">输出: <span class="keyword">true</span></span><br></pre></td></tr></table></figure>

<p><strong>示例 3:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入: nums = [<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>], k = <span class="number">2</span></span><br><span class="line">输出: <span class="keyword">false</span></span><br></pre></td></tr></table></figure>

<p><strong>解法一</strong></p>
<p>这题建议区看看原版的英文题，这里翻译过来有点误导人，应该是不超过k，写个最大搞得我有点懵</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> Boolean <span class="title">containsNearbyDuplicate2</span><span class="params">(<span class="keyword">int</span>[] nums, <span class="keyword">int</span> k)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">int</span> len=nums.length;</span><br><span class="line">    <span class="comment">//if(k==35000) return false; 哈哈哈哈</span></span><br><span class="line">    <span class="keyword">if</span>(len==<span class="number">0</span>||k==<span class="number">0</span>)<span class="keyword">return</span> <span class="keyword">false</span>;</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i=<span class="number">1</span>;i&lt;len;i++) &#123;</span><br><span class="line">        <span class="keyword">int</span> index=i-<span class="number">1</span>;</span><br><span class="line">        <span class="keyword">while</span>(i-index&lt;=k)&#123;</span><br><span class="line">            <span class="comment">//k步之内</span></span><br><span class="line">            <span class="keyword">if</span>(index&lt;<span class="number">0</span>)&#123;</span><br><span class="line">                <span class="keyword">break</span>;</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">if</span>(nums[i]==nums[index--])&#123;</span><br><span class="line">                <span class="keyword">return</span> <span class="keyword">true</span>;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">false</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>暴力法，惨不忍睹，600ms，15%beats 。这题最好的做法还是借助hash表</p>
<p><strong>解法二</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> Boolean <span class="title">containsNearbyDuplicate3</span><span class="params">(<span class="keyword">int</span>[] nums, <span class="keyword">int</span> k)</span> </span>&#123;</span><br><span class="line">    HashMap&lt;Integer,Integer&gt; map=<span class="keyword">new</span> HashMap&lt;&gt;();</span><br><span class="line">    <span class="keyword">int</span> len=nums.length;</span><br><span class="line">    <span class="keyword">if</span>(len==<span class="number">0</span>||k==<span class="number">0</span>) <span class="keyword">return</span> <span class="keyword">false</span>;</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;len;i++) &#123;</span><br><span class="line">        <span class="keyword">if</span>(map.containsKey(nums[i]))&#123;</span><br><span class="line">            <span class="keyword">int</span> index=map.get(nums[i]);</span><br><span class="line">            <span class="keyword">if</span>(i-index&lt;=k) &#123;</span><br><span class="line">                <span class="keyword">return</span> <span class="keyword">true</span>;</span><br><span class="line">            &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                <span class="comment">//大于k了那前面那个没用了</span></span><br><span class="line">                map.replace(nums[i],i);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">            map.put(nums[i],i);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">false</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>12ms，90%，其实效率的差距就在查找子串里有没有这个字符上，HashMap的containsKey的效率比我们遍历的不知道高到那里去了，底层源码暂时还看不太懂，以后看的时候再专门来讲</p>
<p>19.9.14又做了一遍，直接在网页上写的，本来应该是bugfree的，结果减反了。。。</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">boolean</span> <span class="title">containsNearbyDuplicate4</span><span class="params">(<span class="keyword">int</span>[] nums, <span class="keyword">int</span> k)</span> </span>&#123;</span><br><span class="line">	HashMap&lt;Integer,Integer&gt; hashMap=<span class="keyword">new</span> HashMap&lt;&gt;();</span><br><span class="line">	<span class="keyword">int</span> left=<span class="number">0</span>,right=<span class="number">0</span>;</span><br><span class="line">	<span class="keyword">while</span>(right&lt;nums.length)&#123;</span><br><span class="line">		<span class="keyword">if</span>(hashMap.containsKey(nums[right]))&#123;</span><br><span class="line">			<span class="comment">//md,重新做的时候这里减反了真是个zz</span></span><br><span class="line">			<span class="keyword">if</span>(right-hashMap.get(nums[right])&lt;=k)&#123;</span><br><span class="line">				<span class="keyword">return</span> <span class="keyword">true</span>;</span><br><span class="line">			&#125; <span class="keyword">else</span>&#123;</span><br><span class="line">				hashMap.put(nums[right],right);</span><br><span class="line">			&#125;</span><br><span class="line">		&#125;<span class="keyword">else</span>&#123;</span><br><span class="line">			hashMap.put(nums[right],right);</span><br><span class="line">		&#125;</span><br><span class="line">		right++;</span><br><span class="line">	&#125;</span><br><span class="line">	<span class="keyword">return</span> <span class="keyword">false</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>19.9.15又做了一遍，这次代码写的很简洁，思路也不同了，直接利用set集合，维护一个大小为k的连续set(窗口)</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">containsNearbyDuplicate</span><span class="params">(<span class="keyword">int</span>[] nums, <span class="keyword">int</span> k)</span> </span>&#123;</span><br><span class="line">    HashSet&lt;Integer&gt; set=<span class="keyword">new</span> HashSet&lt;&gt;();</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;nums.length;i++) &#123;</span><br><span class="line">        <span class="keyword">if</span> (!set.add(nums[i])) &#123;</span><br><span class="line">            <span class="keyword">return</span> <span class="keyword">true</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span> (set.size()&gt;k) &#123;</span><br><span class="line">            set.remove(nums[i-k]);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">false</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="209-长度最小的子数组"><a href="#209-长度最小的子数组" class="headerlink" title="209. 长度最小的子数组"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/minimum-size-subarray-sum/" >209. 长度最小的子数组<i class="fas fa-external-link-alt"></i></a></h2><p>给定一个含有 <strong>n</strong> 个正整数的数组和一个正整数 <strong>s ，</strong>找出该数组中满足其和 <strong>≥ s</strong> 的长度最小的连续子数组<strong>。</strong>如果不存在符合条件的连续子数组，返回 0。</p>
<p><strong>示例:</strong> </p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入: s = <span class="number">7</span>, nums = [<span class="number">2</span>,<span class="number">3</span>,<span class="number">1</span>,<span class="number">2</span>,<span class="number">4</span>,<span class="number">3</span>]</span><br><span class="line">输出: <span class="number">2</span></span><br><span class="line">解释: 子数组 [<span class="number">4</span>,<span class="number">3</span>] 是该条件下的长度最小的连续子数组。</span><br></pre></td></tr></table></figure>

<p><strong>进阶:</strong></p>
<p>如果你已经完成了<em>O</em>(<em>n</em>) 时间复杂度的解法, 请尝试 <em>O</em>(<em>n</em> log <em>n</em>) 时间复杂度的解法。</p>
<p><strong>解法一</strong></p>
<p>老规矩先上个慢的</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">int</span> <span class="title">minSubArrayLen</span><span class="params">(<span class="keyword">int</span> s, <span class="keyword">int</span>[] nums)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">int</span> len=nums.length;</span><br><span class="line">    <span class="keyword">if</span>(len==<span class="number">0</span>)<span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">int</span> minLen=Integer.MAX_VALUE;</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i=<span class="number">1</span>;i&lt;len;i++)&#123;</span><br><span class="line">        <span class="keyword">if</span>(nums[i-<span class="number">1</span>]&gt;=s) <span class="keyword">return</span> <span class="number">1</span>;</span><br><span class="line">        <span class="keyword">int</span> index=i-<span class="number">1</span>;</span><br><span class="line">        <span class="keyword">int</span> sum=nums[i];</span><br><span class="line">        <span class="comment">//累加前面的元素，直到大于s或者index&lt;0</span></span><br><span class="line">        <span class="keyword">while</span>(sum&lt;s&amp;&amp;index&gt;=<span class="number">0</span>)&#123;</span><br><span class="line">            sum+=nums[index--];</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span>(sum&gt;=s)&#123;</span><br><span class="line">            minLen=minLen&gt;i-index?i-index:minLen;</span><br><span class="line">        &#125; <span class="keyword">else</span> <span class="keyword">if</span>(i==len-<span class="number">1</span>)&#123;</span><br><span class="line">            <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> minLen;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>这个是最开始想到了思路比较清晰，遍历数组然后逆序求和直到大于S，要注意边界，比较慢，主要就是那个循环累加前面的元素会很耗费时间，111ms，14% beats🤣</p>
<p><strong>解法二</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">int</span> <span class="title">minSubArrayLen2</span><span class="params">(<span class="keyword">int</span> s, <span class="keyword">int</span>[] nums)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">int</span> len =nums.length;</span><br><span class="line">    <span class="keyword">if</span>(len==<span class="number">0</span>)<span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">    <span class="comment">//窗口左右边界</span></span><br><span class="line">    <span class="keyword">int</span> head=<span class="number">0</span>,tail=-<span class="number">1</span>;</span><br><span class="line">    <span class="keyword">int</span> minLen=Integer.MAX_VALUE;</span><br><span class="line">    <span class="keyword">int</span> sum=<span class="number">0</span>;</span><br><span class="line">    <span class="comment">// 2,3,1,2,4,3 | 7</span></span><br><span class="line">    <span class="keyword">while</span> (tail&lt;len) &#123;</span><br><span class="line">        <span class="keyword">if</span>(sum&gt;=s)&#123;</span><br><span class="line">            minLen=minLen&gt;tail-head+<span class="number">1</span>?tail-head+<span class="number">1</span>:minLen;</span><br><span class="line">            <span class="comment">//System.out.println(minLen);</span></span><br><span class="line">            <span class="comment">//删除头节点（左边界左移）</span></span><br><span class="line">            sum-=nums[head++];</span><br><span class="line">        &#125; <span class="keyword">else</span>&#123;</span><br><span class="line">            <span class="comment">//尾指针到达边界了</span></span><br><span class="line">            <span class="keyword">if</span>(tail==len-<span class="number">1</span>) <span class="keyword">break</span>;</span><br><span class="line">            <span class="comment">//尾节点++，(右边界右移)</span></span><br><span class="line">            sum+=nums[++tail];</span><br><span class="line">            <span class="comment">//如果有元素大于s直接返回，节约时间</span></span><br><span class="line">            <span class="keyword">if</span>(nums[tail]&gt;=s)&#123;</span><br><span class="line">                <span class="keyword">return</span> <span class="number">1</span>;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> minLen==Integer.MAX_VALUE?<span class="number">0</span>:minLen;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>2ms ，99%beats，一对比差距就出来了，上面这种做法就是利用了滑动窗口的思想，很巧妙的利用了上一次计算的值，不用重复的计算累加和，上面的那种方法每次都会重新计算累加和，但是很多都是重复的计算，所以浪费了很多时间，要注意边界条件</p>
<p><code>2 3 1 2 4 3  s=7</code></p>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="http://static.imlgw.top///20190504/U9BTOJMRVhDO.jpg?imageslim"
                      alt="mark"
                ></p>
<p>自己在纸上画一下就懂了</p>
<p><strong>解法三</strong></p>
<p><del>找到一个模板，统一一下写法</del></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">int</span> <span class="title">minSubArrayLen3</span><span class="params">(<span class="keyword">int</span> s, <span class="keyword">int</span>[] nums)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">int</span> len =nums.length-<span class="number">1</span>;</span><br><span class="line">    <span class="keyword">if</span>(len==<span class="number">0</span>)<span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">int</span> head=<span class="number">0</span>,tail=-<span class="number">1</span>;</span><br><span class="line">    <span class="keyword">int</span> minLen=Integer.MAX_VALUE;</span><br><span class="line">    <span class="keyword">int</span> sum=<span class="number">0</span>;</span><br><span class="line">    <span class="comment">// 2,3,1,2,4,3 | 7</span></span><br><span class="line">    <span class="keyword">while</span> (head&lt;=len) &#123;</span><br><span class="line">        <span class="keyword">if</span>(tail+<span class="number">1</span>&lt;=len &amp;&amp; sum&lt;s)&#123;</span><br><span class="line">            sum+=nums[++tail];</span><br><span class="line">        &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">            sum-=nums[head++];</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span>(sum&gt;=s)&#123;</span><br><span class="line">            minLen=minLen&gt;tail-head+<span class="number">1</span>?tail-head+<span class="number">1</span>:minLen;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> minLen==Integer.MAX_VALUE?<span class="number">0</span>:minLen;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p><strong>Update(2020.5.4)</strong></p>
<p>上面的这也配叫模板？下面的是重做的时候统一的写法</p>
<figure class="highlight go"><table><tr><td class="code"><pre><span class="line"><span class="keyword">var</span> INF = <span class="number">1</span> &lt;&lt; <span class="number">31</span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">minSubArrayLen</span><span class="params">(s <span class="keyword">int</span>, nums []<span class="keyword">int</span>)</span> <span class="title">int</span></span> &#123;</span><br><span class="line">    left := <span class="number">0</span></span><br><span class="line">    sum := <span class="number">0</span></span><br><span class="line">    res := INF</span><br><span class="line">    <span class="keyword">for</span> right := <span class="number">0</span>; right &lt; <span class="built_in">len</span>(nums); right++ &#123;</span><br><span class="line">        sum += nums[right]</span><br><span class="line">        <span class="keyword">for</span> sum &gt;= s &#123;</span><br><span class="line">            res = Min(res, right-left+<span class="number">1</span>)</span><br><span class="line">            sum -= nums[left]</span><br><span class="line">            left++</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span> res == INF &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="number">0</span></span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> res</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">Min</span><span class="params">(a, b <span class="keyword">int</span>)</span> <span class="title">int</span></span> &#123;</span><br><span class="line">    <span class="keyword">if</span> a &lt; b &#123;</span><br><span class="line">        <span class="keyword">return</span> a</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> b</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="面试题57-II-和为s的连续正数序列"><a href="#面试题57-II-和为s的连续正数序列" class="headerlink" title="面试题57 - II. 和为s的连续正数序列"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/he-wei-sde-lian-xu-zheng-shu-xu-lie-lcof/" >面试题57 - II. 和为s的连续正数序列<i class="fas fa-external-link-alt"></i></a></h2><p>输入一个正整数 target ，输出所有和为 target 的连续正整数序列（至少含有两个数）。</p>
<p>序列内的数字由小到大排列，不同序列按照首个数字从小到大排列。</p>
<p><strong>示例 1：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入：target = <span class="number">9</span></span><br><span class="line">输出：[[<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>],[<span class="number">4</span>,<span class="number">5</span>]]</span><br></pre></td></tr></table></figure>


<p><strong>示例 2：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入：target = <span class="number">15</span></span><br><span class="line">输出：[[<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>,<span class="number">5</span>],[<span class="number">4</span>,<span class="number">5</span>,<span class="number">6</span>],[<span class="number">7</span>,<span class="number">8</span>]]</span><br></pre></td></tr></table></figure>

<p><strong>限制：</strong></p>
<ul>
<li><code>1 &lt;= target &lt;= 10^5</code></li>
</ul>
<p><strong>解法一</strong></p>
<p>滑动窗口，根据等差数列前n项和求sum，然后逐步的缩圈，右移</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">int</span>[][] findContinuousSequence(<span class="keyword">int</span> target) &#123;</span><br><span class="line">    List&lt;<span class="keyword">int</span>[]&gt; res=<span class="keyword">new</span> ArrayList&lt;&gt;();</span><br><span class="line">    <span class="keyword">int</span> left=<span class="number">1</span>,right=<span class="number">2</span>;</span><br><span class="line">    <span class="keyword">int</span> sum=<span class="number">0</span>;</span><br><span class="line">    <span class="comment">//9 right最多到5</span></span><br><span class="line">    <span class="keyword">while</span>(left&lt;=right &amp;&amp; right&lt;=(target+<span class="number">1</span>)/<span class="number">2</span>)&#123;</span><br><span class="line">        <span class="comment">//等差数列前n项和</span></span><br><span class="line">        <span class="keyword">int</span> n=right-left+<span class="number">1</span>;</span><br><span class="line">        sum=left*n+n*(n-<span class="number">1</span>)/<span class="number">2</span>;</span><br><span class="line">        <span class="keyword">if</span>(sum&gt;target)&#123;</span><br><span class="line">            left++; <span class="comment">//剔除一个小的</span></span><br><span class="line">        &#125;<span class="keyword">else</span> <span class="keyword">if</span>(sum&lt;target)&#123;</span><br><span class="line">            right++; <span class="comment">//添加一个大的</span></span><br><span class="line">        &#125;<span class="keyword">else</span>&#123; <span class="comment">//build结果集</span></span><br><span class="line">            res.add(build(left,right));</span><br><span class="line">            left++;<span class="comment">//窗口左移,剔除一个小的</span></span><br><span class="line">            right++; <span class="comment">//回头重写发现这里还可以优化,右边界也可以扩大</span></span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> res.toArray(<span class="keyword">new</span> <span class="keyword">int</span>[<span class="number">0</span>][<span class="number">0</span>]);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">int</span>[] build(<span class="keyword">int</span> left,<span class="keyword">int</span> right)&#123;</span><br><span class="line">    <span class="keyword">int</span>[] res=<span class="keyword">new</span> <span class="keyword">int</span>[right-left+<span class="number">1</span>];</span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">int</span> i=left;i&lt;=right;i++)&#123;</span><br><span class="line">        res[i-left]=i;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>这里其实并不是最优解，还有更好的数学解法，直接根据求和公式，枚举所有的长度，逆向求出所有的首项，这里后面有时间再来实现</p>
<h2 id="480-滑动窗口中位数"><a href="#480-滑动窗口中位数" class="headerlink" title="480. 滑动窗口中位数"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/sliding-window-median/" >480. 滑动窗口中位数<i class="fas fa-external-link-alt"></i></a></h2><p>中位数是有序序列最中间的那个数。如果序列的大小是偶数，则没有最中间的数；此时中位数是最中间的两个数的平均数。</p>
<p>例如：</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">[<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>]，中位数是 <span class="number">3</span></span><br><span class="line">[<span class="number">2</span>,<span class="number">3</span>]，中位数是 (<span class="number">2</span> + <span class="number">3</span>) / <span class="number">2</span> = <span class="number">2.5</span></span><br></pre></td></tr></table></figure>

<p>给出一个数组 nums，有一个大小为 <em>k</em> 的窗口从最左端滑动到最右端。窗口中有 k 个数，每次窗口移动 1 位。你的任务是找出每次窗口移动后得到的新窗口中元素的中位数，并输出由它们组成的数组。</p>
<p>例如：</p>
<p>给出 <em>nums</em> = <code>[1,3,-1,-3,5,3,6,7]</code>，以及 <em>k</em> = 3。</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">窗口位置                      中位数</span><br><span class="line">---------------               -----</span><br><span class="line">[<span class="number">1</span>  <span class="number">3</span>  -<span class="number">1</span>] -<span class="number">3</span>  <span class="number">5</span>  <span class="number">3</span>  <span class="number">6</span>  <span class="number">7</span>       <span class="number">1</span></span><br><span class="line"> <span class="number">1</span> [<span class="number">3</span>  -<span class="number">1</span>  -<span class="number">3</span>] <span class="number">5</span>  <span class="number">3</span>  <span class="number">6</span>  <span class="number">7</span>       -<span class="number">1</span></span><br><span class="line"> <span class="number">1</span>  <span class="number">3</span> [-<span class="number">1</span>  -<span class="number">3</span>  <span class="number">5</span>] <span class="number">3</span>  <span class="number">6</span>  <span class="number">7</span>       -<span class="number">1</span></span><br><span class="line"> <span class="number">1</span>  <span class="number">3</span>  -<span class="number">1</span> [-<span class="number">3</span>  <span class="number">5</span>  <span class="number">3</span>] <span class="number">6</span>  <span class="number">7</span>       <span class="number">3</span></span><br><span class="line"> <span class="number">1</span>  <span class="number">3</span>  -<span class="number">1</span>  -<span class="number">3</span> [<span class="number">5</span>  <span class="number">3</span>  <span class="number">6</span>] <span class="number">7</span>       <span class="number">5</span></span><br><span class="line"> <span class="number">1</span>  <span class="number">3</span>  -<span class="number">1</span>  -<span class="number">3</span>  <span class="number">5</span> [<span class="number">3</span>  <span class="number">6</span>  <span class="number">7</span>]      <span class="number">6</span></span><br></pre></td></tr></table></figure>

<p> 因此，返回该滑动窗口的中位数数组 <code>[1,-1,-1,3,5,6]</code>。</p>
<p><strong>提示：</strong><br>假设<code>k</code>是合法的，即：<code>k</code> 始终小于输入的非空数组的元素个数.</p>
<p>head题，理清楚思路后也不难。</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">double</span>[] medianSlidingWindow(<span class="keyword">int</span>[] nums, <span class="keyword">int</span> k) &#123;</span><br><span class="line">    <span class="comment">//看了一圈评论区，大概知道思路了，还是要排序</span></span><br><span class="line">    <span class="comment">//List&lt;Integer&gt; list=new ArrayList&lt;&gt;(); 用链表还是不方便啊</span></span><br><span class="line">    <span class="keyword">int</span> [] queue=<span class="keyword">new</span> <span class="keyword">int</span>[k];</span><br><span class="line">    <span class="keyword">int</span> head=<span class="number">0</span>,tail=k-<span class="number">1</span>;</span><br><span class="line">    <span class="comment">//头尾</span></span><br><span class="line">    <span class="keyword">double</span> [] res=<span class="keyword">new</span> <span class="keyword">double</span>[nums.length-k+<span class="number">1</span>];</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;k;i++) &#123;</span><br><span class="line">        queue[i]=nums[i];</span><br><span class="line">    &#125;</span><br><span class="line">    Arrays.sort(queue);</span><br><span class="line">    printArray(queue);</span><br><span class="line">    <span class="keyword">if</span> (k%<span class="number">2</span>==<span class="number">0</span>) &#123;</span><br><span class="line">        res[<span class="number">0</span>]=queue[(k-<span class="number">1</span>)/<span class="number">2</span>]/<span class="number">2.0</span>+queue[(k-<span class="number">1</span>)/<span class="number">2</span>+<span class="number">1</span>]/<span class="number">2.0</span>;</span><br><span class="line">        <span class="comment">//注意除小数 .。。。。这里的测试用例Integer最大值，直接相加/2会越界</span></span><br><span class="line">    &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">        res[<span class="number">0</span>]=queue[k/<span class="number">2</span>];</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i=k;i&lt;nums.length;i++) &#123;</span><br><span class="line">        <span class="comment">//插入之前要移除上一次的头元素，这里用数组不好搞啊啊</span></span><br><span class="line">        <span class="comment">//System.out.println(nums[i-k]);</span></span><br><span class="line">        deleHead(queue,nums[i-k]);</span><br><span class="line">        tail--;</span><br><span class="line">        <span class="comment">//printArray(queue);</span></span><br><span class="line">        <span class="comment">//二分找插入点</span></span><br><span class="line">        <span class="keyword">int</span> index=binarySearch(queue,<span class="number">0</span>,tail,nums[i]);</span><br><span class="line">        System.out.println(index);</span><br><span class="line">        tail++;</span><br><span class="line">        <span class="comment">//插入元素，tail++;</span></span><br><span class="line">        <span class="keyword">for</span> (<span class="keyword">int</span> j=tail;j&gt;index;j--) &#123;</span><br><span class="line">            <span class="comment">//后一个等于前一个，给插入的元素腾出位置</span></span><br><span class="line">            queue[j]=queue[j-<span class="number">1</span>];</span><br><span class="line">        &#125;</span><br><span class="line">        queue[index]=nums[i];</span><br><span class="line">        <span class="comment">//求中点</span></span><br><span class="line">        <span class="keyword">if</span> (k%<span class="number">2</span>==<span class="number">0</span>) &#123;</span><br><span class="line">            res[i-k+<span class="number">1</span>]=queue[head+(tail-head)/<span class="number">2</span>]/<span class="number">2.0</span>+queue[head+(tail-head)/<span class="number">2</span>+<span class="number">1</span>]/<span class="number">2.0</span>;</span><br><span class="line">        &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">            res[i-k+<span class="number">1</span>]=queue[head+(tail-head)/<span class="number">2</span>];</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">deleHead</span><span class="params">(<span class="keyword">int</span> []nums,<span class="keyword">int</span> target)</span></span>&#123;</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> j=<span class="number">0</span>,i=<span class="number">0</span>;j&lt;nums.length;j++,i++) &#123;</span><br><span class="line">        <span class="keyword">if</span>(nums[j]==target)&#123;</span><br><span class="line">            <span class="keyword">if</span> (i==nums.length-<span class="number">1</span>) &#123;</span><br><span class="line">                <span class="keyword">return</span>;</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">while</span>(i&lt;nums.length-<span class="number">1</span>)&#123;</span><br><span class="line">                nums[i]=nums[i+<span class="number">1</span>];</span><br><span class="line">                i++;</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">return</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span>  <span class="keyword">static</span> <span class="keyword">int</span> <span class="title">binarySearch</span><span class="params">(<span class="keyword">int</span> []nums,<span class="keyword">int</span> lo,<span class="keyword">int</span> hi,<span class="keyword">int</span> target)</span></span>&#123;</span><br><span class="line">    <span class="keyword">while</span>(lo&lt;=hi)&#123;</span><br><span class="line">        <span class="keyword">int</span> mid=lo+(hi-lo)/<span class="number">2</span>;</span><br><span class="line">        <span class="keyword">if</span>(nums[mid]&lt;target)&#123;</span><br><span class="line">            lo=mid+<span class="number">1</span>;</span><br><span class="line">        &#125; <span class="keyword">else</span> <span class="keyword">if</span>(nums[mid]&gt;target)&#123;</span><br><span class="line">            hi=mid-<span class="number">1</span>;</span><br><span class="line">        &#125; <span class="keyword">else</span>&#123;</span><br><span class="line">            <span class="keyword">return</span> mid;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> lo;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>根据评论区提供的思路，用数组实现了一遍，当时就感觉有问题，确实，最后 164ms ，27%，很慢了，我觉得主要问题就是那个删除头的操作，但是毕竟数组，没办法，随即改用链表</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">double</span>[] medianSlidingWindow2(<span class="keyword">int</span>[] nums, <span class="keyword">int</span> k) &#123;</span><br><span class="line">    <span class="comment">//看了一圈评论区，大概知道思路了，还是要排序</span></span><br><span class="line">    List&lt;Integer&gt; list=<span class="keyword">new</span> ArrayList&lt;&gt;();</span><br><span class="line">    <span class="keyword">int</span> head=<span class="number">0</span>,tail=k-<span class="number">1</span>;</span><br><span class="line">    <span class="comment">//头尾</span></span><br><span class="line">    <span class="keyword">double</span> [] res=<span class="keyword">new</span> <span class="keyword">double</span>[nums.length-k+<span class="number">1</span>];</span><br><span class="line">    <span class="comment">//Arrays.sort(nums,0,k);</span></span><br><span class="line">    <span class="keyword">int</span> []temp=<span class="keyword">new</span> <span class="keyword">int</span>[k];</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;k;i++) &#123;</span><br><span class="line">        temp[i]=nums[i];</span><br><span class="line">    &#125;</span><br><span class="line">    Arrays.sort(temp);</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;k;i++) &#123;</span><br><span class="line">        list.add(temp[i]);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span> (k%<span class="number">2</span>==<span class="number">0</span>) &#123;</span><br><span class="line">        res[<span class="number">0</span>]=list.get((k-<span class="number">1</span>)/<span class="number">2</span>)/<span class="number">2.0</span>+list.get((k-<span class="number">1</span>)/<span class="number">2</span>+<span class="number">1</span>)/<span class="number">2.0</span>;</span><br><span class="line">    &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">        res[<span class="number">0</span>]=list.get(k/<span class="number">2</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i=k;i&lt;nums.length;i++) &#123;</span><br><span class="line">        <span class="comment">//插入之前要移除上一次的头元素，这里用数组不好搞啊啊</span></span><br><span class="line">        <span class="comment">//list.remove((Object)nums[i-k]); 直接删太慢了</span></span><br><span class="line">        <span class="keyword">int</span> dele=binarySearch(list,<span class="number">0</span>,k-<span class="number">1</span>,nums[i-k]);</span><br><span class="line">        list.remove(dele);</span><br><span class="line">        <span class="comment">//System.out.println(list);</span></span><br><span class="line">        <span class="comment">//二分找插入点，找的区间为 [i-k+1, i-1]</span></span><br><span class="line">        <span class="comment">//int head=i-k+1,tail=i-1;</span></span><br><span class="line">        <span class="keyword">int</span> index=binarySearch(list,<span class="number">0</span>,k-<span class="number">2</span>,nums[i]);</span><br><span class="line">        System.out.println(index);</span><br><span class="line">        list.add(-<span class="number">1</span>);</span><br><span class="line">        <span class="keyword">for</span> (<span class="keyword">int</span> j=k-<span class="number">1</span>;j&gt;index;j--) &#123;</span><br><span class="line">            <span class="comment">//后一个等于前一个，给插入的元素腾出位置</span></span><br><span class="line">            list.set(j,list.get(j-<span class="number">1</span>));</span><br><span class="line">        &#125;</span><br><span class="line">        list.set(index,nums[i]);</span><br><span class="line">        System.out.println(list);</span><br><span class="line">        <span class="comment">//求中点</span></span><br><span class="line">        <span class="keyword">if</span> (k%<span class="number">2</span>==<span class="number">0</span>) &#123;</span><br><span class="line">            res[i-k+<span class="number">1</span>]=list.get((k-<span class="number">1</span>)/<span class="number">2</span>) / <span class="number">2.0</span> + list.get((k-<span class="number">1</span>)/<span class="number">2</span>+<span class="number">1</span>)/<span class="number">2.0</span>;</span><br><span class="line">        &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">            res[i-k+<span class="number">1</span>]=list.get(k/<span class="number">2</span>);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br><span class="line"><span class="function"><span class="keyword">public</span>  <span class="keyword">static</span> <span class="keyword">int</span> <span class="title">binarySearch</span><span class="params">(List&lt;Integer&gt; list,<span class="keyword">int</span> lo,<span class="keyword">int</span> hi,<span class="keyword">int</span> target)</span></span>&#123;</span><br><span class="line">    <span class="keyword">while</span>(lo&lt;=hi)&#123;</span><br><span class="line">        <span class="keyword">int</span> mid=lo+(hi-lo)/<span class="number">2</span>;</span><br><span class="line">        <span class="keyword">if</span>(list.get(mid)&lt;target)&#123;</span><br><span class="line">            lo=mid+<span class="number">1</span>;</span><br><span class="line">        &#125; <span class="keyword">else</span> <span class="keyword">if</span>(list.get(mid)&gt;target)&#123;</span><br><span class="line">            hi=mid-<span class="number">1</span>;</span><br><span class="line">        &#125; <span class="keyword">else</span>&#123;</span><br><span class="line">            <span class="keyword">return</span> mid;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> lo;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>47ms，70%左右，删除的时候利用二分删除，如果直接根据元素去删就跟数组效率差不多了。</p>
<h2 id="76-最小覆盖子串"><a href="#76-最小覆盖子串" class="headerlink" title="76. 最小覆盖子串"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/minimum-window-substring/" >76. 最小覆盖子串<i class="fas fa-external-link-alt"></i></a></h2><p>给你一个字符串 S、一个字符串 T，请在字符串 S 里面找出：包含 T 所有字母的最小子串。</p>
<p><strong>示例：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入: S = <span class="string">&quot;ADOBECODEBANC&quot;</span>, T = <span class="string">&quot;ABC&quot;</span></span><br><span class="line">输出: <span class="string">&quot;BANC&quot;</span></span><br></pre></td></tr></table></figure>

<p><strong>说明：</strong></p>
<ul>
<li>如果 S 中不存这样的子串，则返回空字符串 “”。</li>
<li>如果 S 中存在这样的子串，我们保证它是唯一的答案。</li>
</ul>
<p><strong>解法一</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> String <span class="title">minWindow</span><span class="params">(String s, String t)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">int</span> slen=s.length();</span><br><span class="line">    <span class="keyword">int</span> tlen=t.length();</span><br><span class="line">    <span class="keyword">int</span> l=<span class="number">0</span>,r=<span class="number">0</span>; <span class="comment">//初始都为0</span></span><br><span class="line">    <span class="keyword">int</span>[] target=<span class="keyword">new</span> <span class="keyword">int</span>[<span class="number">256</span>]; <span class="comment">//A:1 B:1 C:1</span></span><br><span class="line">    <span class="keyword">int</span>[] window=<span class="keyword">new</span> <span class="keyword">int</span>[<span class="number">256</span>];</span><br><span class="line">    <span class="keyword">int</span> count=<span class="number">0</span>; <span class="comment">//不同字符的数量</span></span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;tlen;i++) &#123;</span><br><span class="line">        target[t.charAt(i)]++;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> a:target) &#123;</span><br><span class="line">        <span class="keyword">if</span> (a!=<span class="number">0</span>) &#123;</span><br><span class="line">            count++; <span class="comment">//统计不同字符出现的次数</span></span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">int</span> match=<span class="number">0</span>; <span class="comment">//match代表已经匹配的字符</span></span><br><span class="line">    <span class="keyword">int</span>[] res=<span class="keyword">new</span> <span class="keyword">int</span>[]&#123;<span class="number">0</span>,Integer.MAX_VALUE&#125;;</span><br><span class="line">    <span class="keyword">while</span>(r&lt;slen)&#123;</span><br><span class="line">        <span class="keyword">char</span> c=s.charAt(r); </span><br><span class="line">        <span class="keyword">if</span>(target[c]!=<span class="number">0</span>)&#123; <span class="comment">//在目标子串中存在</span></span><br><span class="line">            window[c]++; <span class="comment">//window对应的char++</span></span><br><span class="line">            <span class="keyword">if</span>(window[c]==target[c])&#123; <span class="comment">//到达了目标串中该char所需的数量</span></span><br><span class="line">                match++;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        r++;</span><br><span class="line">        <span class="keyword">while</span>(l&lt;r&amp;&amp;count==match) &#123; <span class="comment">//满足目标串，注意别越界</span></span><br><span class="line">            <span class="keyword">char</span> d=s.charAt(l);</span><br><span class="line">            <span class="keyword">if</span> (r-l&lt;res[<span class="number">1</span>]-res[<span class="number">0</span>]) &#123; <span class="comment">//统计最小值</span></span><br><span class="line">                res[<span class="number">0</span>]=l;</span><br><span class="line">                res[<span class="number">1</span>]=r;</span><br><span class="line">            &#125;</span><br><span class="line">            l++;</span><br><span class="line">            <span class="keyword">if</span> (target[d]!=<span class="number">0</span>) &#123;</span><br><span class="line">                window[d]--;</span><br><span class="line">                <span class="keyword">if</span> (window[d]&lt;target[d]) &#123;<span class="comment">//左边界左移后不再满足目标串</span></span><br><span class="line">                    match--;</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> res[<span class="number">1</span>]==Integer.MAX_VALUE?<span class="string">&quot;&quot;</span>:s.substring(res[<span class="number">0</span>],res[<span class="number">1</span>]);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>10ms 86%，Hard题，其实大致的思路还是有的，主要是不知道怎么去和目标串对比，没想到用一个<code>window</code>数组去对比，一致想的是在目标串的数组上做手脚，但是越想越复杂。。。太蠢了😅，这题其实也可以用一个HashMap来做，但是我看了下提交记录上的普遍都是7,80ms，相对都比较慢，实际上题目没有明确的说明有特殊字符的话都是可以用一个<strong>ASCII</strong>数组来充当HashMap的，当然我这里用数组的时候相比HashMap要多了一步，需要统计不同字符出现的次数，不过这个操作也是常数级别的操作，并不耗时，整体时间复杂度O(N+M)，NM分别代表目标子串<code>t</code> 和源字符串 <code>p</code>的长度，首先遍历了<code>t</code> 然后滑动窗口，后面的滑动窗口左右边界最多移动2M次</p>
<p><strong>Update</strong></p>
<p>2020.4.15，在瞄了一眼之前做的之后按照之前的思路重写了一遍，感觉还行，有一个地方WA了一次</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">//update: 2020.4.15</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> String <span class="title">minWindow</span><span class="params">(String s, String t)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span>(s==<span class="keyword">null</span> || t==<span class="keyword">null</span>) <span class="keyword">return</span> <span class="string">&quot;&quot;</span>;</span><br><span class="line">    <span class="keyword">int</span>[] needMap=<span class="keyword">new</span> <span class="keyword">int</span>[<span class="number">128</span>]; <span class="comment">//需要的字符map</span></span><br><span class="line">    <span class="keyword">int</span>[] curMap=<span class="keyword">new</span> <span class="keyword">int</span>[<span class="number">128</span>];  <span class="comment">//已经匹配的字符map</span></span><br><span class="line">    <span class="keyword">int</span> needCount=<span class="number">0</span>; <span class="comment">//需要匹配的字符个数</span></span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;t.length();i++)&#123;</span><br><span class="line">        <span class="keyword">if</span>(needMap[t.charAt(i)]==<span class="number">0</span>)&#123;</span><br><span class="line">            needCount++;</span><br><span class="line">        &#125;</span><br><span class="line">        needMap[t.charAt(i)]++;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">int</span> matchCount=<span class="number">0</span>; <span class="comment">//已经匹配的个数</span></span><br><span class="line">    <span class="keyword">int</span> left=<span class="number">0</span>,right=<span class="number">0</span>;</span><br><span class="line">    <span class="keyword">int</span> minLeft=<span class="number">0</span>,maxRight=Integer.MAX_VALUE;</span><br><span class="line">    <span class="keyword">while</span>(left&lt;=right &amp;&amp; right&lt;s.length())&#123;</span><br><span class="line">        <span class="keyword">char</span> c=s.charAt(right);</span><br><span class="line">        <span class="keyword">if</span>(needMap[c]!=<span class="number">0</span>)&#123;</span><br><span class="line">            curMap[c]++;</span><br><span class="line">            <span class="keyword">if</span>(curMap[c]==needMap[c])&#123;</span><br><span class="line">                matchCount++;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">while</span>(left&lt;=right &amp;&amp; right&lt;s.length() &amp;&amp; matchCount==needCount)&#123;</span><br><span class="line">            <span class="keyword">if</span>(right-left&lt;maxRight-minLeft)&#123;</span><br><span class="line">                maxRight=right;</span><br><span class="line">                minLeft=left;</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">char</span> cl=s.charAt(left);</span><br><span class="line">            <span class="keyword">if</span>(curMap[cl]!=<span class="number">0</span>)&#123;</span><br><span class="line">                curMap[cl]--;</span><br><span class="line">                <span class="comment">//这里注意，WA点，开始写的=0</span></span><br><span class="line">                <span class="keyword">if</span>(curMap[cl]&lt;needMap[cl])&#123;</span><br><span class="line">                    matchCount--;</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">            left++;</span><br><span class="line">        &#125;</span><br><span class="line">        right++;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> Integer.MAX_VALUE==maxRight?<span class="string">&quot;&quot;</span>:s.substring(minLeft,maxRight+<span class="number">1</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<blockquote>
<p>刷题的时候发现有一道很类似的题，<a href="http://imlgw.top/2019/09/01/leetcode-dong-tai-gui-hua/#857-%E6%9C%80%E5%B0%8F%E7%9A%84%E7%AA%97%E5%8F%A3%E5%AD%90%E5%BA%8F%E5%88%97%EF%BC%88LintCode%EF%BC%89">最小窗口子序列</a>唯一的区别就是这道题要求有序（子序列）</p>
</blockquote>
<h2 id="632-最小区间"><a href="#632-最小区间" class="headerlink" title="632. 最小区间"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/smallest-range-covering-elements-from-k-lists/" >632. 最小区间<i class="fas fa-external-link-alt"></i></a></h2><p>Difficulty: <strong>困难</strong></p>
<p>你有 <code>k</code> 个升序排列的整数数组。找到一个<strong>最小</strong>区间，使得 <code>k</code> 个列表中的每个列表至少有一个数包含在其中。</p>
<p>我们定义如果 <code>b-a &lt; d-c</code> 或者在 <code>b-a == d-c</code> 时 <code>a &lt; c</code>，则区间 [a,b] 比 [c,d] 小。</p>
<p><strong>示例 1:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入:[[<span class="number">4</span>,<span class="number">10</span>,<span class="number">15</span>,<span class="number">24</span>,<span class="number">26</span>], [<span class="number">0</span>,<span class="number">9</span>,<span class="number">12</span>,<span class="number">20</span>], [<span class="number">5</span>,<span class="number">18</span>,<span class="number">22</span>,<span class="number">30</span>]]</span><br><span class="line">输出: [<span class="number">20</span>,<span class="number">24</span>]</span><br><span class="line">解释: </span><br><span class="line">列表 <span class="number">1</span>：[<span class="number">4</span>, <span class="number">10</span>, <span class="number">15</span>, <span class="number">24</span>, <span class="number">26</span>]，<span class="number">24</span> 在区间 [<span class="number">20</span>,<span class="number">24</span>] 中。</span><br><span class="line">列表 <span class="number">2</span>：[<span class="number">0</span>, <span class="number">9</span>, <span class="number">12</span>, <span class="number">20</span>]，<span class="number">20</span> 在区间 [<span class="number">20</span>,<span class="number">24</span>] 中。</span><br><span class="line">列表 <span class="number">3</span>：[<span class="number">5</span>, <span class="number">18</span>, <span class="number">22</span>, <span class="number">30</span>]，<span class="number">22</span> 在区间 [<span class="number">20</span>,<span class="number">24</span>] 中。</span><br></pre></td></tr></table></figure>

<p><strong>注意:</strong></p>
<ol>
<li> 给定的列表可能包含重复元素，所以在这里升序表示 &gt;= 。</li>
<li> 1 &lt;= <code>k</code> &lt;= 3500</li>
<li> -10<sup>5</sup> &lt;= <code>元素的值</code> &lt;= 10<sup>5</sup></li>
</ol>
<p><strong>解法一</strong></p>
<figure class="highlight golang"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">smallestRange</span><span class="params">(nums [][]<span class="keyword">int</span>)</span> []<span class="title">int</span></span> &#123;</span><br><span class="line">    <span class="keyword">var</span> n = <span class="built_in">len</span>(nums)</span><br><span class="line">    <span class="comment">//列表中所有元素k,存在于那些数组中</span></span><br><span class="line">    <span class="keyword">var</span> m = <span class="built_in">make</span>(<span class="keyword">map</span>[<span class="keyword">int</span>][]<span class="keyword">int</span>)</span><br><span class="line">    <span class="keyword">var</span> Max = <span class="function"><span class="keyword">func</span> <span class="params">(a, b <span class="keyword">int</span>)</span> <span class="title">int</span></span> &#123;<span class="keyword">if</span> a &gt; b &#123;<span class="keyword">return</span> a&#125;; <span class="keyword">return</span> b&#125;</span><br><span class="line">    <span class="keyword">var</span> Min = <span class="function"><span class="keyword">func</span> <span class="params">(a, b <span class="keyword">int</span>)</span> <span class="title">int</span></span> &#123;<span class="keyword">if</span> a &lt; b &#123;<span class="keyword">return</span> a&#125;; <span class="keyword">return</span> b&#125;</span><br><span class="line">    <span class="comment">//记录最大最小值，然后在区间内滑窗，也可以直接将所有数组归并排一下，然后滑窗，比较麻烦，懒得写了</span></span><br><span class="line">    <span class="comment">//所以下面的做法实际上是和循序无关的，没有用到有序这个条件</span></span><br><span class="line">    <span class="keyword">var</span> maxV = math.MinInt32</span><br><span class="line">    <span class="keyword">var</span> minV = math.MaxInt32</span><br><span class="line">    <span class="keyword">for</span> i :=<span class="number">0</span>; i &lt; n; i++ &#123;</span><br><span class="line">        <span class="keyword">for</span> j := <span class="number">0</span>; j &lt; <span class="built_in">len</span>(nums[i]); j++ &#123;</span><br><span class="line">            m[nums[i][j]] = <span class="built_in">append</span>(m[nums[i][j]], i)</span><br><span class="line">            maxV = Max(maxV, nums[i][j])</span><br><span class="line">            minV = Min(minV, nums[i][j])</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">//同 76.最小覆盖子串，这题可能思维的转换比较重要</span></span><br><span class="line">    <span class="keyword">var</span> count = <span class="number">0</span></span><br><span class="line">    <span class="keyword">var</span> freq = <span class="built_in">make</span>([]<span class="keyword">int</span>, n+<span class="number">1</span>)</span><br><span class="line">    <span class="keyword">var</span> res =[]<span class="keyword">int</span>&#123;minV, maxV&#125;</span><br><span class="line">    <span class="keyword">var</span> left = minV</span><br><span class="line">    <span class="keyword">for</span> right := minV; right &lt;= maxV; right++ &#123;</span><br><span class="line">        <span class="keyword">if</span> lis, ok := m[right]; ok &#123;</span><br><span class="line">            <span class="keyword">for</span> _, numIdx := <span class="keyword">range</span> lis &#123;</span><br><span class="line">                freq[numIdx]++</span><br><span class="line">                <span class="keyword">if</span> freq[numIdx] == <span class="number">1</span>&#123;</span><br><span class="line">                    count++</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">for</span> count == n &amp;&amp; left &lt;= right &#123;</span><br><span class="line">            <span class="keyword">if</span> right-left &lt; res[<span class="number">1</span>]-res[<span class="number">0</span>] &#123;</span><br><span class="line">                res[<span class="number">0</span>] = left</span><br><span class="line">                res[<span class="number">1</span>] = right</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">if</span> lis, ok := m[left]; ok&#123;</span><br><span class="line">                <span class="keyword">for</span> _, numIdx := <span class="keyword">range</span> lis &#123;</span><br><span class="line">                    freq[numIdx]--</span><br><span class="line">                    <span class="keyword">if</span> freq[numIdx] &lt; <span class="number">1</span> &#123;</span><br><span class="line">                        count--</span><br><span class="line">                    &#125;</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">            left++</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> res</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p><strong>解法二</strong></p>
<p>上面的解法并不是最好的解法，没有用到有序的条件，比较好的解法应该是小根堆（本来打算用Go撸一个的，写一半感觉太麻烦了，不过整体小根堆的逻辑实现是对的，就是没有泛型要改很多东西，不太方便）<br><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="https://i.loli.net/2020/11/30/Q5KsxNi3MquZtWE.png"
                     
                ><br>维护两个最值，一个是找到一个能覆盖当前所有列表的最小的右端点（max），一个是当前列表最小的那个元素（最左的端点），然后不断缩减左端点求最小区间</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Node</span> </span>&#123;</span><br><span class="line">    <span class="keyword">int</span> i, j;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="title">Node</span> <span class="params">(<span class="keyword">int</span> i, <span class="keyword">int</span> j)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">this</span>.i = i;</span><br><span class="line">        <span class="keyword">this</span>.j = j;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//k组链表，平均m个元素，时间复杂度 O(kmlog(k))</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">int</span>[] smallestRange(List&lt;List&lt;Integer&gt;&gt; nums) &#123;</span><br><span class="line">    PriorityQueue&lt;Node&gt; pq = <span class="keyword">new</span> PriorityQueue&lt;&gt;((a, b) -&gt; nums.get(a.i).get(a.j)-nums.get(b.i).get(b.j));</span><br><span class="line">    <span class="keyword">int</span> INF = (<span class="keyword">int</span>) <span class="number">1e5</span>+<span class="number">1</span>;</span><br><span class="line">    <span class="keyword">int</span> max = Integer.MIN_VALUE;</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; nums.size(); i++) &#123;</span><br><span class="line">        pq.add(<span class="keyword">new</span> Node(i, <span class="number">0</span>));</span><br><span class="line">        max = Math.max(max, nums.get(i).get(<span class="number">0</span>));</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">int</span> [] res = &#123;-INF, INF&#125;;</span><br><span class="line">    <span class="keyword">while</span> (<span class="keyword">true</span>) &#123;</span><br><span class="line">        Node cur = pq.poll();</span><br><span class="line">        <span class="comment">//应该把val也存进去的，懒得改了</span></span><br><span class="line">        <span class="keyword">if</span> (max-nums.get(cur.i).get(cur.j) &lt; res[<span class="number">1</span>]-res[<span class="number">0</span>]) &#123;</span><br><span class="line">            res[<span class="number">0</span>] = nums.get(cur.i).get(cur.j);</span><br><span class="line">            res[<span class="number">1</span>] = max;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span> (cur.j+<span class="number">1</span> &gt;= nums.get(cur.i).size()) &#123;</span><br><span class="line">            <span class="keyword">break</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        pq.add(<span class="keyword">new</span> Node(cur.i, cur.j+<span class="number">1</span>));</span><br><span class="line">        max = Math.max(max, nums.get(cur.i).get(cur.j+<span class="number">1</span>));</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="438-找到字符串中所有字母异位词"><a href="#438-找到字符串中所有字母异位词" class="headerlink" title="438. 找到字符串中所有字母异位词"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/find-all-anagrams-in-a-string/" >438. 找到字符串中所有字母异位词<i class="fas fa-external-link-alt"></i></a></h2><p>给定一个字符串 <strong>s</strong> 和一个非空字符串 <strong>p</strong>，找到 <strong>s</strong> 中所有是 <strong>p</strong> 的字母异位词的子串，返回这些子串的起始索引。</p>
<p>字符串只包含小写英文字母，并且字符串 <strong>s</strong> 和 <strong>p</strong> 的长度都不超过 20100。</p>
<p><strong>说明：</strong></p>
<ul>
<li>字母异位词指字母相同，但排列不同的字符串。</li>
<li>不考虑答案输出的顺序。</li>
</ul>
<p><strong>示例 1:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入:</span><br><span class="line">s: <span class="string">&quot;cbaebabacd&quot;</span> p: <span class="string">&quot;abc&quot;</span></span><br><span class="line">输出:</span><br><span class="line">[<span class="number">0</span>, <span class="number">6</span>]</span><br><span class="line"></span><br><span class="line">解释:</span><br><span class="line">起始索引等于 <span class="number">0</span> 的子串是 <span class="string">&quot;cba&quot;</span>, 它是 <span class="string">&quot;abc&quot;</span> 的字母异位词。</span><br><span class="line">起始索引等于 <span class="number">6</span> 的子串是 <span class="string">&quot;bac&quot;</span>, 它是 <span class="string">&quot;abc&quot;</span> 的字母异位词。</span><br></pre></td></tr></table></figure>

<p> <strong>示例 2:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入:</span><br><span class="line">s: <span class="string">&quot;abab&quot;</span> p: <span class="string">&quot;ab&quot;</span></span><br><span class="line"></span><br><span class="line">输出:</span><br><span class="line">[<span class="number">0</span>, <span class="number">1</span>, <span class="number">2</span>]</span><br><span class="line"></span><br><span class="line">解释:</span><br><span class="line">起始索引等于 <span class="number">0</span> 的子串是 <span class="string">&quot;ab&quot;</span>, 它是 <span class="string">&quot;ab&quot;</span> 的字母异位词。</span><br><span class="line">起始索引等于 <span class="number">1</span> 的子串是 <span class="string">&quot;ba&quot;</span>, 它是 <span class="string">&quot;ab&quot;</span> 的字母异位词。</span><br><span class="line">起始索引等于 <span class="number">2</span> 的子串是 <span class="string">&quot;ab&quot;</span>, 它是 <span class="string">&quot;ab&quot;</span> 的字母异位词。</span><br></pre></td></tr></table></figure>

<p><strong>解法一</strong></p>
<p>这题和上面一题其实一样，只是这里要求是连续的，在上面一题的基础上在添加结果的时候判断下长度就OK</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> List&lt;Integer&gt; <span class="title">findAnagrams</span><span class="params">(String s, String p)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">int</span>[] target=<span class="keyword">new</span> <span class="keyword">int</span>[<span class="number">256</span>];</span><br><span class="line">    <span class="keyword">int</span>[] window=<span class="keyword">new</span> <span class="keyword">int</span>[<span class="number">256</span>];</span><br><span class="line">    <span class="keyword">int</span> l=<span class="number">0</span>,r=<span class="number">0</span>;</span><br><span class="line">    <span class="keyword">int</span> plen=p.length();</span><br><span class="line">    <span class="keyword">int</span> slen=s.length();</span><br><span class="line">    <span class="keyword">int</span> count=<span class="number">0</span>,match=<span class="number">0</span>;</span><br><span class="line">    List&lt;Integer&gt; res=<span class="keyword">new</span> ArraysList&lt;&gt;();</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;plen;i++) &#123;</span><br><span class="line">        target[p.charAt(i)]++;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> a:target) &#123;</span><br><span class="line">        <span class="keyword">if</span>(a!=<span class="number">0</span>)&#123;</span><br><span class="line">            count++;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">while</span>(r&lt;slen)&#123;</span><br><span class="line">        <span class="keyword">char</span> right=s.charAt(r);</span><br><span class="line">        <span class="keyword">if</span> (target[right]!=<span class="number">0</span>) &#123;</span><br><span class="line">            window[right]++;</span><br><span class="line">            <span class="keyword">if</span> (window[right]==target[right]) &#123;</span><br><span class="line">                match++;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        r++;</span><br><span class="line">        <span class="keyword">while</span>(l&lt;r &amp;&amp; count==match)&#123;</span><br><span class="line">            <span class="keyword">char</span> left=s.charAt(l);</span><br><span class="line">            <span class="keyword">if</span> (r-l==res) &#123;</span><br><span class="line">                res.add(l);</span><br><span class="line">            &#125;</span><br><span class="line">            l++;</span><br><span class="line">            <span class="keyword">if</span> (target[left]!=<span class="number">0</span>) &#123;</span><br><span class="line">                window[left]--;</span><br><span class="line">                <span class="comment">//不满足了</span></span><br><span class="line">                <span class="keyword">if</span> (window[left]&lt;target[left]) &#123;</span><br><span class="line">                    match--;</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p><strong>UPDATE:2020.7.23</strong></p>
<p>用模板重写了下</p>
<figure class="highlight golang"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">findAnagrams</span><span class="params">(s <span class="keyword">string</span>, p <span class="keyword">string</span>)</span> []<span class="title">int</span></span> &#123;</span><br><span class="line">    <span class="keyword">var</span> target = <span class="built_in">make</span>([]<span class="keyword">int</span>, <span class="number">128</span>)</span><br><span class="line">    <span class="keyword">var</span> window = <span class="built_in">make</span>([]<span class="keyword">int</span>, <span class="number">128</span>)</span><br><span class="line">    <span class="keyword">var</span> match = <span class="number">0</span></span><br><span class="line">    <span class="keyword">for</span> _, sp := <span class="keyword">range</span> p &#123;</span><br><span class="line">        <span class="keyword">if</span> target[sp] == <span class="number">0</span> &#123;</span><br><span class="line">            match++</span><br><span class="line">        &#125;</span><br><span class="line">        target[sp]++</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">var</span> left = <span class="number">0</span></span><br><span class="line">    <span class="keyword">var</span> count = <span class="number">0</span></span><br><span class="line">    <span class="keyword">var</span> res []<span class="keyword">int</span></span><br><span class="line">    <span class="keyword">for</span> right := <span class="number">0</span>; right &lt; <span class="built_in">len</span>(s); right++ &#123;</span><br><span class="line">        <span class="keyword">if</span> target[s[right]] &gt; <span class="number">0</span> &#123;</span><br><span class="line">            window[s[right]]++</span><br><span class="line">            <span class="keyword">if</span> window[s[right]] == target[s[right]] &#123;</span><br><span class="line">                count++</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">for</span> count == match &amp;&amp; left &lt;= right &#123;</span><br><span class="line">            <span class="keyword">if</span> right-left+<span class="number">1</span> == <span class="built_in">len</span>(p) &#123;</span><br><span class="line">                res = <span class="built_in">append</span>(res, left)</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">if</span> window[s[left]] &gt; <span class="number">0</span> &#123;</span><br><span class="line">                window[s[left]]--</span><br><span class="line">                <span class="keyword">if</span> window[s[left]] &lt; target[s[left]] &#123;</span><br><span class="line">                    count--</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">            left++</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> res</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>15ms，86%时间复杂度<code>O(M+N)</code>，其实是完全套的之前最小覆盖子串的模板，不如肯定不好写这么长</p>
<p><strong>解法二</strong></p>
<p>正常的做法，实际上上面的解法一直在避免直接比较target和window，但是实际上比较这两个数组的成本是很低的，两个数组长度固定，比较时间复杂度O(1)，具体情况具体分析，不过套模板几乎是通用的</p>
<figure class="highlight golang"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">findAnagrams</span><span class="params">(s <span class="keyword">string</span>, p <span class="keyword">string</span>)</span> []<span class="title">int</span></span> &#123;</span><br><span class="line">    <span class="keyword">var</span> left = <span class="number">0</span></span><br><span class="line">    <span class="comment">//-&#x27;a&#x27;看起来太丑了，直接128</span></span><br><span class="line">    <span class="keyword">var</span> target [<span class="number">128</span>]<span class="keyword">int</span> <span class="comment">//注意用数组，可以直接比较</span></span><br><span class="line">    <span class="keyword">var</span> window [<span class="number">128</span>]<span class="keyword">int</span></span><br><span class="line">    <span class="keyword">for</span> _, sp := <span class="keyword">range</span> p &#123;</span><br><span class="line">        target[sp]++</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">var</span> res []<span class="keyword">int</span></span><br><span class="line">    <span class="keyword">for</span> right := <span class="number">0</span>; right &lt; <span class="built_in">len</span>(s); right++ &#123;</span><br><span class="line">        <span class="keyword">if</span> target[s[right]] &gt; <span class="number">0</span> &#123;</span><br><span class="line">            window[s[right]]++</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">for</span> right-left+<span class="number">1</span> &gt; <span class="built_in">len</span>(p) &#123;</span><br><span class="line">            <span class="keyword">if</span> window[s[left]] &gt; <span class="number">0</span> &#123;</span><br><span class="line">                window[s[left]]--</span><br><span class="line">            &#125;</span><br><span class="line">            left++</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span> window == target &#123;</span><br><span class="line">            res = <span class="built_in">append</span>(res, left)</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> res</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="567-字符串的排列"><a href="#567-字符串的排列" class="headerlink" title="567. 字符串的排列"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/permutation-in-string/" >567. 字符串的排列<i class="fas fa-external-link-alt"></i></a></h2><p>给定两个字符串 <strong>s1</strong> 和 <strong>s2</strong>，写一个函数来判断 <strong>s2</strong> 是否包含 <strong>s1</strong> 的排列。</p>
<p>换句话说，第一个字符串的排列之一是第二个字符串的子串。</p>
<p><strong>示例1:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入: s1 = <span class="string">&quot;ab&quot;</span> s2 = <span class="string">&quot;eidbaooo&quot;</span></span><br><span class="line">输出: True</span><br><span class="line">解释: s2 包含 s1 的排列之一 (<span class="string">&quot;ba&quot;</span>).</span><br></pre></td></tr></table></figure>

<p><strong>示例2:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入: s1= <span class="string">&quot;ab&quot;</span> s2 = <span class="string">&quot;eidboaoo&quot;</span></span><br><span class="line">输出: False</span><br></pre></td></tr></table></figure>

<p><strong>注意：</strong></p>
<ol>
<li>输入的字符串只包含小写字母</li>
<li>两个字符串的长度都在 [1, 10,000] 之间</li>
</ol>
<p><strong>解法一</strong></p>
<p>这题其实是 <a href="#76-%E6%9C%80%E5%B0%8F%E8%A6%86%E7%9B%96%E5%AD%90%E4%B8%B2">76.最小覆盖子串</a> 的弱化版本，套路滑窗，但是有一些细节需要注意</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">checkInclusion</span><span class="params">(String s1, String s2)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span>(s1==<span class="keyword">null</span> || s2==<span class="keyword">null</span> || s1.length()&gt;s2.length())&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">false</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">int</span> n1=s1.length();</span><br><span class="line">    <span class="keyword">int</span> n2=s2.length();</span><br><span class="line">    <span class="keyword">int</span>[] freq=<span class="keyword">new</span> <span class="keyword">int</span>[<span class="number">26</span>];</span><br><span class="line">    <span class="keyword">int</span> count=<span class="number">0</span>;</span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;n1;i++)&#123;</span><br><span class="line">        <span class="keyword">int</span> c=s1.charAt(i)-<span class="string">&#x27;a&#x27;</span>;</span><br><span class="line">        <span class="keyword">if</span>(freq[c]==<span class="number">0</span>)&#123;</span><br><span class="line">            count++;</span><br><span class="line">        &#125;</span><br><span class="line">        freq[c]++;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">int</span>[] window=<span class="keyword">new</span> <span class="keyword">int</span>[<span class="number">26</span>];</span><br><span class="line">    <span class="keyword">int</span> match=<span class="number">0</span>;</span><br><span class="line">    <span class="keyword">int</span> left=<span class="number">0</span>;</span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">int</span> right=<span class="number">0</span>;right&lt;n2;right++)&#123;</span><br><span class="line">        <span class="keyword">int</span> cr=s2.charAt(right)-<span class="string">&#x27;a&#x27;</span>;</span><br><span class="line">        <span class="keyword">if</span>(freq[cr]&gt;<span class="number">0</span>)&#123;</span><br><span class="line">            window[cr]++;</span><br><span class="line">            <span class="keyword">if</span>(window[cr]==freq[cr])&#123;</span><br><span class="line">                match++;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">while</span>(right-left+<span class="number">1</span>&gt;n1)&#123;</span><br><span class="line">            <span class="keyword">int</span> cl=s2.charAt(left)-<span class="string">&#x27;a&#x27;</span>;</span><br><span class="line">            <span class="keyword">if</span>(freq[cl]&gt;<span class="number">0</span>)&#123;</span><br><span class="line">                <span class="comment">//WA点，开始写错了</span></span><br><span class="line">                <span class="comment">//window[cl]--;</span></span><br><span class="line">                <span class="keyword">if</span>(window[cl]==freq[cl])&#123;</span><br><span class="line">                    match--; <span class="comment">//match--的前提是原本是匹配的</span></span><br><span class="line">                &#125;</span><br><span class="line">                window[cl]--;</span><br><span class="line">            &#125;</span><br><span class="line">            left++;</span><br><span class="line">        &#125; </span><br><span class="line">        <span class="keyword">if</span>(match==count)&#123;</span><br><span class="line">            <span class="keyword">return</span> <span class="keyword">true</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">false</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>一开始写完了，测试了用例发现都是对的，心里一喜，难道又bugfree了？提交，结果还是WA了🤣，debug了半天，根据错误的哪个长case自己构造了一个短case（长的不好debug），然后发现了问题，这个问题我看见评论区也有人问到，顺手还回了一下😁，其实错误的原因就是套模板没套好，没理解模板的细节</p>
<p>这里的核心问题就是<code>match--</code>的时候有一个大前提：<code>cl</code>字符已经匹配好了，也就是<code>window[cl]==freq[cl]</code></p>
<p>这个时候你<code>left++</code>将<code>cl</code>移除窗口，才能做<code>match--</code>操作，否则像之前的模板中</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">if</span> (target[left]!=<span class="number">0</span>) &#123;</span><br><span class="line">    window[left]--;</span><br><span class="line">    <span class="comment">//不满足了</span></span><br><span class="line">    <span class="keyword">if</span> (window[left]&lt;target[left]) &#123;</span><br><span class="line">        match--;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>这样写就有可能window[left]还没有匹配上，这个时候直接减就错了，之前的模板中缩圈都是在match==count的前提下缩圈的，所以没问题，都是匹配的，其实也可以像之前的模板一样写，就像下面这样</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">checkInclusion</span><span class="params">(String s1, String s2)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span>(s1==<span class="keyword">null</span> || s2==<span class="keyword">null</span> || s1.length()&gt;s2.length())&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">false</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">int</span> n1=s1.length();</span><br><span class="line">    <span class="keyword">int</span> n2=s2.length();</span><br><span class="line">    <span class="keyword">int</span>[] freq=<span class="keyword">new</span> <span class="keyword">int</span>[<span class="number">26</span>];</span><br><span class="line">    <span class="keyword">int</span> count=<span class="number">0</span>;</span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;n1;i++)&#123;</span><br><span class="line">        <span class="keyword">int</span> c=s1.charAt(i)-<span class="string">&#x27;a&#x27;</span>;</span><br><span class="line">        <span class="keyword">if</span>(freq[c]==<span class="number">0</span>)&#123;</span><br><span class="line">            count++;</span><br><span class="line">        &#125;</span><br><span class="line">        freq[c]++;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">int</span>[] window=<span class="keyword">new</span> <span class="keyword">int</span>[<span class="number">26</span>];</span><br><span class="line">    <span class="keyword">int</span> match=<span class="number">0</span>;</span><br><span class="line">    <span class="keyword">int</span> left=<span class="number">0</span>;</span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">int</span> right=<span class="number">0</span>;right&lt;n2;right++)&#123;</span><br><span class="line">        <span class="keyword">int</span> cr=s2.charAt(right)-<span class="string">&#x27;a&#x27;</span>;</span><br><span class="line">        <span class="keyword">if</span>(freq[cr]&gt;<span class="number">0</span>)&#123;</span><br><span class="line">            window[cr]++;</span><br><span class="line">            <span class="keyword">if</span>(window[cr]==freq[cr])&#123;</span><br><span class="line">                match++;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="comment">//****************************</span></span><br><span class="line">        <span class="comment">//主要就是这里不一样</span></span><br><span class="line">        <span class="keyword">while</span>(match==count)&#123;</span><br><span class="line">            <span class="keyword">if</span>(right-left+<span class="number">1</span>==n1) <span class="keyword">return</span> <span class="keyword">true</span>;</span><br><span class="line">            <span class="keyword">int</span> cl=s2.charAt(left)-<span class="string">&#x27;a&#x27;</span>;</span><br><span class="line">            <span class="keyword">if</span>(freq[cl]&gt;<span class="number">0</span>)&#123;</span><br><span class="line">                window[cl]--;</span><br><span class="line">                <span class="keyword">if</span>(window[cl]&lt;freq[cl])&#123;</span><br><span class="line">                    match--;</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">            left++;</span><br><span class="line">        &#125; </span><br><span class="line">        <span class="comment">//****************************</span></span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">false</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>这样就不用考虑先减还是后减的问题了</p>
<p><strong>解法二</strong></p>
<p>这题其实还可以暴力做，窗口大小固定，每滑动一次就判断窗口和<code>freq</code>是不是相等，因为题目说了都是小写字母所以也是行得通的，只是常数会大一些，这里我就不写了，笔试推荐这样写，代码好写一点</p>
<h2 id="面试题-17-18-最短超串"><a href="#面试题-17-18-最短超串" class="headerlink" title="面试题 17.18. 最短超串"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/shortest-supersequence-lcci/" >面试题 17.18. 最短超串<i class="fas fa-external-link-alt"></i></a></h2><p>假设你有两个数组，一个长一个短，短的元素均不相同。找到长数组中包含短数组所有的元素的最短子数组，其出现顺序无关紧要。</p>
<p>返回最短子数组的左端点和右端点，如有多个满足条件的子数组，返回左端点最小的一个。若不存在，返回空数组。</p>
<p><strong>示例 1:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入:</span><br><span class="line">big = [<span class="number">7</span>,<span class="number">5</span>,<span class="number">9</span>,<span class="number">0</span>,<span class="number">2</span>,<span class="number">1</span>,<span class="number">3</span>,<span class="number">5</span>,<span class="number">7</span>,<span class="number">9</span>,<span class="number">1</span>,<span class="number">1</span>,<span class="number">5</span>,<span class="number">8</span>,<span class="number">8</span>,<span class="number">9</span>,<span class="number">7</span>]</span><br><span class="line">small = [<span class="number">1</span>,<span class="number">5</span>,<span class="number">9</span>]</span><br><span class="line">输出: [<span class="number">7</span>,<span class="number">10</span>]</span><br></pre></td></tr></table></figure>

<p><strong>示例 2:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入:</span><br><span class="line">big = [<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>]</span><br><span class="line">small = [<span class="number">4</span>]</span><br><span class="line">输出: []</span><br></pre></td></tr></table></figure>

<p><strong>提示：</strong></p>
<ul>
<li><code>big.length &lt;= 100000</code></li>
<li><code>1 &lt;= small.length &lt;= 100000</code></li>
</ul>
<p><strong>解法一</strong></p>
<p>也是属于 <a href="#76-%E6%9C%80%E5%B0%8F%E8%A6%86%E7%9B%96%E5%AD%90%E4%B8%B2">76.最小覆盖子串</a>的弱化，虽然解法都一样，没啥好说的，注意细节</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">//没啥好说的，套模板就行了</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">int</span>[] shortestSeq(<span class="keyword">int</span>[] big, <span class="keyword">int</span>[] small) &#123;</span><br><span class="line">    <span class="keyword">if</span>(big==<span class="keyword">null</span> || big.length&lt;=<span class="number">0</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">new</span> <span class="keyword">int</span>[<span class="number">0</span>];</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">int</span> slen=small.length;</span><br><span class="line">    <span class="keyword">int</span> blen=big.length;</span><br><span class="line">    <span class="keyword">int</span>[] res=<span class="keyword">new</span> <span class="keyword">int</span>[<span class="number">2</span>];</span><br><span class="line">    res[<span class="number">0</span>]=-<span class="number">1</span>;res[<span class="number">1</span>]=-<span class="number">1</span>;</span><br><span class="line">    <span class="keyword">int</span> min=Integer.MAX_VALUE;</span><br><span class="line">    HashSet&lt;Integer&gt; set=<span class="keyword">new</span> HashSet&lt;&gt;();</span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">int</span> i:small) set.add(i);</span><br><span class="line">    HashMap&lt;Integer,Integer&gt; window=<span class="keyword">new</span> HashMap&lt;&gt;();</span><br><span class="line">    <span class="keyword">int</span> match=<span class="number">0</span>;</span><br><span class="line">    <span class="keyword">int</span> left=<span class="number">0</span>;</span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">int</span> right=<span class="number">0</span>;right&lt;blen;right++)&#123;</span><br><span class="line">        <span class="keyword">int</span> wr=big[right];</span><br><span class="line">        <span class="keyword">if</span>(set.contains(wr))&#123;</span><br><span class="line">            window.put(wr,window.getOrDefault(wr,<span class="number">0</span>)+<span class="number">1</span>);</span><br><span class="line">            <span class="keyword">if</span>(window.get(wr)==<span class="number">1</span>)&#123;</span><br><span class="line">                match++;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">while</span>(match==slen)&#123;</span><br><span class="line">            <span class="keyword">if</span>(right-left+<span class="number">1</span>&lt;min)&#123;</span><br><span class="line">                res[<span class="number">0</span>]=left;</span><br><span class="line">                res[<span class="number">1</span>]=right;</span><br><span class="line">                min=right-left+<span class="number">1</span>;</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">int</span> wl=big[left];</span><br><span class="line">            <span class="keyword">if</span>(set.contains(wl))&#123;</span><br><span class="line">                window.put(wl,window.get(wl)-<span class="number">1</span>);</span><br><span class="line">                <span class="keyword">if</span>(window.get(wl)==<span class="number">0</span>)&#123;</span><br><span class="line">                    match--;</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">            left++;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> res[<span class="number">0</span>]==-<span class="number">1</span>?<span class="keyword">new</span> <span class="keyword">int</span>[<span class="number">0</span>]:res;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="1004-最大连续1的个数-III"><a href="#1004-最大连续1的个数-III" class="headerlink" title="1004. 最大连续1的个数 III"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/max-consecutive-ones-iii/" >1004. 最大连续1的个数 III<i class="fas fa-external-link-alt"></i></a></h2><p>给定一个由若干 <code>0</code> 和 <code>1</code> 组成的数组 <code>A</code>，我们最多可以将 <code>K</code> 个值从 0 变成 1 。</p>
<p>返回仅包含 1 的最长（连续）子数组的长度。</p>
<p><strong>示例 1：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入：A = [<span class="number">1</span>,<span class="number">1</span>,<span class="number">1</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">1</span>,<span class="number">1</span>,<span class="number">1</span>,<span class="number">1</span>,<span class="number">0</span>], K = <span class="number">2</span></span><br><span class="line">输出：<span class="number">6</span></span><br><span class="line">解释： </span><br><span class="line">[<span class="number">1</span>,<span class="number">1</span>,<span class="number">1</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">1</span>,<span class="number">1</span>,<span class="number">1</span>,<span class="number">1</span>,<span class="number">1</span>,<span class="number">1</span>]</span><br><span class="line">粗体数字从 <span class="number">0</span> 翻转到 <span class="number">1</span>，最长的子数组长度为 <span class="number">6</span>。</span><br></pre></td></tr></table></figure>

<p><strong>示例 2：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入：A = [<span class="number">0</span>,<span class="number">0</span>,<span class="number">1</span>,<span class="number">1</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">1</span>,<span class="number">1</span>,<span class="number">1</span>,<span class="number">0</span>,<span class="number">1</span>,<span class="number">1</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">1</span>,<span class="number">1</span>,<span class="number">1</span>,<span class="number">1</span>], K = <span class="number">3</span></span><br><span class="line">输出：<span class="number">10</span></span><br><span class="line">解释：</span><br><span class="line">[<span class="number">0</span>,<span class="number">0</span>,<span class="number">1</span>,<span class="number">1</span>,<span class="number">1</span>,<span class="number">1</span>,<span class="number">1</span>,<span class="number">1</span>,<span class="number">1</span>,<span class="number">1</span>,<span class="number">1</span>,<span class="number">1</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">1</span>,<span class="number">1</span>,<span class="number">1</span>,<span class="number">1</span>]</span><br><span class="line">粗体数字从 <span class="number">0</span> 翻转到 <span class="number">1</span>，最长的子数组长度为 <span class="number">10</span>。</span><br></pre></td></tr></table></figure>

<p><strong>提示：</strong></p>
<ol>
<li><code>1 &lt;= A.length &lt;= 20000</code></li>
<li><code>0 &lt;= K &lt;= A.length</code></li>
<li><code>A[i]</code> 为 <code>0</code> 或 <code>1</code> </li>
</ol>
<p><strong>解法一</strong></p>
<p>这题其实下面一题<a href="#424-%E6%9B%BF%E6%8D%A2%E5%90%8E%E7%9A%84%E6%9C%80%E9%95%BF%E9%87%8D%E5%A4%8D%E5%AD%97%E7%AC%A6">424. 替换后的最长重复字符</a>的弱化版本</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">//简单的滑窗</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">longestOnes</span><span class="params">(<span class="keyword">int</span>[] A, <span class="keyword">int</span> K)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span>(A==<span class="keyword">null</span> || A.length&lt;=<span class="number">0</span>) <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">int</span> N=A.length;</span><br><span class="line">    <span class="keyword">int</span> left=<span class="number">0</span>,res=<span class="number">0</span>,countA=<span class="number">0</span>;</span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">int</span> right=<span class="number">0</span>;right&lt;N;right++)&#123;</span><br><span class="line">        countA+=(A[right]&amp;<span class="number">1</span>);</span><br><span class="line">        <span class="comment">//if也可以，个人喜欢while通用性更强</span></span><br><span class="line">        <span class="keyword">while</span>(right-left+<span class="number">1</span>-countA&gt;K)&#123; </span><br><span class="line">            countA-=(A[left++]&amp;<span class="number">1</span>);</span><br><span class="line">        &#125;</span><br><span class="line">        res=Math.max(res,right-left+<span class="number">1</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>按照模板来写简直是信手拈来（其实也没有什么模板，就是规范了写法而已）</p>
<h2 id="5434-删掉一个元素以后全为-1-的最长子数组"><a href="#5434-删掉一个元素以后全为-1-的最长子数组" class="headerlink" title="5434. 删掉一个元素以后全为 1 的最长子数组"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/longest-subarray-of-1s-after-deleting-one-element/" >5434. 删掉一个元素以后全为 1 的最长子数组<i class="fas fa-external-link-alt"></i></a></h2><p>Difficulty: <strong>中等</strong></p>
<p>给你一个二进制数组 <code>nums</code> ，你需要从中删掉一个元素。</p>
<p>请你在删掉元素的结果数组中，返回最长的且只包含 1 的非空子数组的长度。</p>
<p>如果不存在这样的子数组，请返回 0 。</p>
<p><strong>提示 1：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入：nums = [<span class="number">1</span>,<span class="number">1</span>,<span class="number">0</span>,<span class="number">1</span>]</span><br><span class="line">输出：<span class="number">3</span></span><br><span class="line">解释：删掉位置 <span class="number">2</span> 的数后，[<span class="number">1</span>,<span class="number">1</span>,<span class="number">1</span>] 包含 <span class="number">3</span> 个 <span class="number">1</span> 。</span><br></pre></td></tr></table></figure>

<p><strong>示例 2：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入：nums = [<span class="number">0</span>,<span class="number">1</span>,<span class="number">1</span>,<span class="number">1</span>,<span class="number">0</span>,<span class="number">1</span>,<span class="number">1</span>,<span class="number">0</span>,<span class="number">1</span>]</span><br><span class="line">输出：<span class="number">5</span></span><br><span class="line">解释：删掉位置 <span class="number">4</span> 的数字后，[<span class="number">0</span>,<span class="number">1</span>,<span class="number">1</span>,<span class="number">1</span>,<span class="number">1</span>,<span class="number">1</span>,<span class="number">0</span>,<span class="number">1</span>] 的最长全 <span class="number">1</span> 子数组为 [<span class="number">1</span>,<span class="number">1</span>,<span class="number">1</span>,<span class="number">1</span>,<span class="number">1</span>] 。</span><br></pre></td></tr></table></figure>

<p><strong>示例 3：</strong></p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">输入：nums = [1,1,1]</span><br><span class="line">输出：2</span><br><span class="line">解释：你必须要删除一个元素。</span><br></pre></td></tr></table></figure>

<p><strong>示例 4：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入：nums = [<span class="number">1</span>,<span class="number">1</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">1</span>,<span class="number">1</span>,<span class="number">1</span>,<span class="number">0</span>,<span class="number">1</span>]</span><br><span class="line">输出：<span class="number">4</span></span><br></pre></td></tr></table></figure>

<p><strong>示例 5：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入：nums = [<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>]</span><br><span class="line">输出：<span class="number">0</span></span><br></pre></td></tr></table></figure>

<p><strong>提示：</strong></p>
<ul>
<li>  <code>1 &lt;= nums.length &lt;= 10^5</code></li>
<li>  <code>nums[i]</code> 要么是 <code>0</code> 要么是 <code>1</code> 。</li>
</ul>
<p><strong>解法一</strong></p>
<p>29th双周赛的t3，秒切，其实是上一题<a href="#1004-%E6%9C%80%E5%A4%A7%E8%BF%9E%E7%BB%AD1%E7%9A%84%E4%B8%AA%E6%95%B0-iii">1004. 最大连续1的个数 III</a>的弱化</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">   <span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">longestSubarray</span><span class="params">(<span class="keyword">int</span>[] nums)</span> </span>&#123;</span><br><span class="line">       <span class="keyword">int</span> res=<span class="number">0</span>, sum=<span class="number">0</span>;</span><br><span class="line">       <span class="keyword">int</span> left=<span class="number">0</span>;</span><br><span class="line">       <span class="keyword">for</span>(<span class="keyword">int</span> right=<span class="number">0</span>;right&lt;nums.length;right++)&#123;</span><br><span class="line">           sum+=(nums[right]&amp;<span class="number">1</span>);</span><br><span class="line">           <span class="comment">//区间和小于right-left-1说明中间不止一个0需要缩减窗口</span></span><br><span class="line">           <span class="keyword">while</span>(left&lt;right &amp;&amp; sum&lt;= right-left-<span class="number">1</span>)&#123;</span><br><span class="line">               <span class="keyword">if</span>(nums[left] == <span class="number">1</span>)&#123;</span><br><span class="line">                   sum--;</span><br><span class="line">               &#125;</span><br><span class="line">               left++;</span><br><span class="line">           &#125;</span><br><span class="line">           <span class="comment">//至少删除一个，所以不用+1</span></span><br><span class="line">           res = Math.max(res,right-left);</span><br><span class="line">       &#125;</span><br><span class="line">       <span class="keyword">return</span> res;</span><br><span class="line">   &#125;</span><br></pre></td></tr></table></figure>
<p>很可惜这次前3题15分钟就做完了，都是直接web上写的，本以为有机会AK，最后一题搞了半天最后交了一发还是没过，貌似很多人写了假算法，贪心莽过了（lc数据太弱了）<br><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="https://upload.cc/i1/2020/06/28/mhTiQ9.png"
                      alt="UTOOLS1593333299362.png"
                ></p>
<h2 id="424-替换后的最长重复字符"><a href="#424-替换后的最长重复字符" class="headerlink" title="424. 替换后的最长重复字符"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/longest-repeating-character-replacement/" >424. 替换后的最长重复字符<i class="fas fa-external-link-alt"></i></a></h2><p>给你一个仅由大写英文字母组成的字符串，你可以将任意位置上的字符替换成另外的字符，总共可最多替换 k 次。在执行上述操作后，找到包含重复字母的最长子串的长度。</p>
<p><strong>注意:</strong><br>字符串长度 和 k 不会超过 104。</p>
<p><strong>示例 1:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入:</span><br><span class="line">s = <span class="string">&quot;ABAB&quot;</span>, k = <span class="number">2</span></span><br><span class="line">输出:</span><br><span class="line"><span class="number">4</span></span><br><span class="line">解释:</span><br><span class="line">用两个<span class="string">&#x27;A&#x27;</span>替换为两个<span class="string">&#x27;B&#x27;</span>,反之亦然。</span><br></pre></td></tr></table></figure>

<p><strong>示例 2:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入:</span><br><span class="line">s = <span class="string">&quot;AABABBA&quot;</span>, k = <span class="number">1</span></span><br><span class="line">输出:</span><br><span class="line"><span class="number">4</span></span><br><span class="line">解释:</span><br><span class="line">将中间的一个<span class="string">&#x27;A&#x27;</span>替换为<span class="string">&#x27;B&#x27;</span>,字符串变为 <span class="string">&quot;AABBBBA&quot;</span></span><br><span class="line">子串 <span class="string">&quot;BBBB&quot;</span> 有最长重复字母, 答案为 <span class="number">4</span></span><br></pre></td></tr></table></figure>

<p><strong>解法一</strong></p>
<p>上面一题的加强版</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">characterReplacement</span><span class="params">(String s, <span class="keyword">int</span> k)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">int</span> max = <span class="number">0</span>, start = <span class="number">0</span>, end = <span class="number">0</span>, cur = -<span class="number">1</span>;</span><br><span class="line">    <span class="keyword">int</span>[] count = <span class="keyword">new</span> <span class="keyword">int</span>[<span class="number">256</span>];</span><br><span class="line">    <span class="keyword">while</span> (end &lt; s.length()) &#123;</span><br><span class="line">        <span class="comment">//当前窗口出现最多的字符</span></span><br><span class="line">        cur = Math.max(cur, ++count[s.charAt(end)]);</span><br><span class="line">        <span class="comment">//不能替换了,不同字符太多了,需要缩减窗口</span></span><br><span class="line">        <span class="keyword">while</span> (end - start + <span class="number">1</span> - cur &gt; k)&#123;</span><br><span class="line">            <span class="comment">//缩减左边界的count</span></span><br><span class="line">            count[s.charAt(start)]--;</span><br><span class="line">            start++;<span class="comment">//不能替换了，start++</span></span><br><span class="line">        &#125;</span><br><span class="line">        <span class="comment">//统计最大值</span></span><br><span class="line">        max = Math.max(max, end - start + <span class="number">1</span>);</span><br><span class="line">        end++;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> max;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p><strong>UPDATE: (2020.5.5)</strong></p>
<p>按照模板重写，果然滑窗的题都是一样的</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">characterReplacement</span><span class="params">(String s, <span class="keyword">int</span> k)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span>(s==<span class="keyword">null</span> || s.length()&lt;=<span class="number">0</span>)&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">int</span> n=s.length();</span><br><span class="line">    <span class="keyword">int</span> res=<span class="number">1</span>;</span><br><span class="line">    <span class="keyword">int</span> left=<span class="number">0</span>;</span><br><span class="line">    <span class="keyword">int</span>[] freq=<span class="keyword">new</span> <span class="keyword">int</span>[<span class="number">128</span>];</span><br><span class="line">    <span class="keyword">int</span> maxFreq=<span class="number">0</span>;</span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">int</span> right=<span class="number">0</span>;right&lt;n;right++)&#123;</span><br><span class="line">        <span class="keyword">char</span> c=s.charAt(right);</span><br><span class="line">        freq[c]++;</span><br><span class="line">        maxFreq=Math.max(maxFreq,freq[c]);</span><br><span class="line">        <span class="keyword">while</span>((right-left+<span class="number">1</span>-maxFreq)&gt;k)&#123;</span><br><span class="line">            freq[s.charAt(left)]--;</span><br><span class="line">            left++; <span class="comment">//这里实际上只会执行一次，改成if也是可以的，不过为了统一写法就不改了</span></span><br><span class="line">        &#125;</span><br><span class="line">        res=Math.max(res,right-left+<span class="number">1</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>重写这题的时候发现这题还是挺有意思的，这个里面的<code>maxFreq</code>是一个只增不减的量，是一个历史最大值，只有当出现更大的freq的时候才会更新<code>maxFreq</code>，当<code>maxFreq</code>保持不变的时候结果不会受到影响，只有出现了更大freq的时候才有可能会使结果变大</p>
<blockquote>
<p><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/longest-repeating-character-replacement/solution/hua-dong-chuang-kou-chang-gui-tao-lu-by-xiaoneng/" >拷贝自题解区<i class="fas fa-external-link-alt"></i></a> </p>
<p>因为我们只对最长有效的子字符串感兴趣，所以我们的滑动窗口不需要收缩，即使窗口可能覆盖无效的子字符串。我们可以通过在右边添加一个字符来扩展窗口，或者将整个窗口向右边移动一个字符。而且我们只在新字符的计数超过历史最大计数(来自覆盖有效子字符串的前一个窗口)时才增长窗口。也就是说，我们不需要精确的当前窗口的最大计数;我们只关心最大计数是否超过历史最大计数;这只会因为新字符而发生。</p>
</blockquote>
<p><strong>解法二</strong></p>
<p>憨憨的解法，不过绝对是能AC的，时间复杂度并没有问题，依然是<code>O(N)</code></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">characterReplacement</span><span class="params">(String s, <span class="keyword">int</span> k)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span>(s==<span class="keyword">null</span> || s.length()&lt;=<span class="number">0</span>)&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">int</span> n=s.length();</span><br><span class="line">    <span class="keyword">int</span> res=<span class="number">1</span>;</span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">int</span> c=<span class="string">&#x27;A&#x27;</span>;c&lt;=<span class="string">&#x27;Z&#x27;</span>;c++)&#123;</span><br><span class="line">        <span class="keyword">int</span>[] freq=<span class="keyword">new</span> <span class="keyword">int</span>[<span class="number">128</span>];</span><br><span class="line">        <span class="keyword">int</span> temp=<span class="number">1</span>;</span><br><span class="line">        <span class="keyword">int</span> left=<span class="number">0</span>;</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> right=<span class="number">0</span>;right&lt;n;right++)&#123;</span><br><span class="line">            <span class="keyword">if</span>(s.charAt(right)==c)&#123;</span><br><span class="line">                freq[c]++;</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">while</span>((right-left+<span class="number">1</span>-freq[c])&gt;k)&#123;</span><br><span class="line">                <span class="keyword">if</span>(s.charAt(left)==c)&#123;</span><br><span class="line">                    freq[c]--;</span><br><span class="line">                &#125;</span><br><span class="line">                left++;</span><br><span class="line">            &#125;</span><br><span class="line">            temp=Math.max(temp,right-left+<span class="number">1</span>);</span><br><span class="line">        &#125;</span><br><span class="line">        res=Math.max(res,temp);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>既然题目说了只有大写字母，那就直接枚举所有的字符然后滑窗就行了😂，简单直白</p>
<h2 id="1234-替换子串得到平衡字符串"><a href="#1234-替换子串得到平衡字符串" class="headerlink" title="1234. 替换子串得到平衡字符串"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/replace-the-substring-for-balanced-string/" >1234. 替换子串得到平衡字符串<i class="fas fa-external-link-alt"></i></a></h2><p>有一个只含有 <code>&#39;Q&#39;, &#39;W&#39;, &#39;E&#39;, &#39;R&#39;</code> 四种字符，且长度为 n 的字符串。</p>
<p>假如在该字符串中，这四个字符都恰好出现 <code>n/4</code> 次，那么它就是一个「平衡字符串」。</p>
<p>给你一个这样的字符串 <code>s</code>，请通过「替换子串」的方式，使原字符串 s 变成一个「平衡字符串」。</p>
<p>你可以用和「待替换子串」长度相同的 任何 其他字符串来完成替换。</p>
<p>请返回待替换子串的最小可能长度。</p>
<p>如果原字符串自身就是一个平衡字符串，则返回 0 </p>
<p><strong>示例 1：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入：s = <span class="string">&quot;QWER&quot;</span></span><br><span class="line">输出：<span class="number">0</span></span><br><span class="line">解释：s 已经是平衡的了。</span><br></pre></td></tr></table></figure>

<p><strong>示例 2：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入：s = <span class="string">&quot;QQWE&quot;</span></span><br><span class="line">输出：<span class="number">1</span></span><br><span class="line">解释：我们需要把一个 <span class="string">&#x27;Q&#x27;</span> 替换成 <span class="string">&#x27;R&#x27;</span>，这样得到的 <span class="string">&quot;RQWE&quot;</span> (或 <span class="string">&quot;QRWE&quot;</span>) 是平衡的。</span><br></pre></td></tr></table></figure>

<p><strong>示例 3：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入：s = <span class="string">&quot;QQQW&quot;</span></span><br><span class="line">输出：<span class="number">2</span></span><br><span class="line">解释：我们可以把前面的 <span class="string">&quot;QQ&quot;</span> 替换成 <span class="string">&quot;ER&quot;</span>。 </span><br></pre></td></tr></table></figure>

<p><strong>示例 4：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入：s = <span class="string">&quot;QQQQ&quot;</span></span><br><span class="line">输出：<span class="number">3</span></span><br><span class="line">解释：我们可以替换后 <span class="number">3</span> 个 <span class="string">&#x27;Q&#x27;</span>，使 s = <span class="string">&quot;QWER&quot;</span>。</span><br></pre></td></tr></table></figure>

<p><strong>提示：</strong></p>
<ul>
<li>1 &lt;= s.length &lt;= 10^5</li>
<li>s.length 是 4 的倍数</li>
<li>s 中只含有 ‘Q’, ‘W’, ‘E’, ‘R’ 四种字符</li>
</ul>
<p><strong>解法一</strong></p>
<p>周赛题，说实话不多做做竞赛真不知道自己多菜</p>
<p>(update: 2020.4.15)</p>
<p>我拿到这题，首先想到的是无脑套路滑窗，既然要保证平衡，那么每个字符出现的次数都应该是<code>N/4</code>，所以我们可以统计下多出来的有几个，比如<code>QQQW</code>，那么多出来的就是2个**<code>Q</code><strong>，也就是说我们要求的窗口内</strong>至少**有2个Q，这样问题其实就转换成了 <a href="#76-%E6%9C%80%E5%B0%8F%E8%A6%86%E7%9B%96%E5%AD%90%E4%B8%B2">76. 最小覆盖子串</a>（这明明是个mid题，你咋还给转换成hard了，你是不是傻🤣）</p>
<p>其实最小覆盖子串看起来好像挺难，但是是有套路的，我们直接套模板就可以了</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">balancedString</span><span class="params">(String s)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span>(s==<span class="keyword">null</span> || s.length()&lt;=<span class="number">0</span>) <span class="keyword">return</span> -<span class="number">1</span>;</span><br><span class="line">    <span class="keyword">int</span> N=s.length();</span><br><span class="line">    <span class="comment">//这里用26有的浪费,为了方便写代码,就这样吧</span></span><br><span class="line">    <span class="keyword">int</span>[] need=<span class="keyword">new</span> <span class="keyword">int</span>[<span class="number">26</span>];</span><br><span class="line">    <span class="comment">//初始化为-N/4这样最后得到的大于0的值就是多出来的</span></span><br><span class="line">    Arrays.fill(need,-N/<span class="number">4</span>);</span><br><span class="line">    <span class="keyword">int</span>[] cur=<span class="keyword">new</span> <span class="keyword">int</span>[<span class="number">26</span>];</span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;N;i++)&#123;</span><br><span class="line">        need[s.charAt(i)-<span class="string">&#x27;A&#x27;</span>]++;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">//有几个字符多出来了</span></span><br><span class="line">    <span class="keyword">int</span> needCount=<span class="number">0</span>; </span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;need.length;i++)&#123;</span><br><span class="line">        <span class="keyword">if</span>(need[i]&gt;<span class="number">0</span>) needCount++;</span><br><span class="line">    &#125; </span><br><span class="line">    <span class="keyword">if</span>(needCount==<span class="number">0</span>) <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">int</span> res=N;</span><br><span class="line">    <span class="keyword">int</span> left=<span class="number">0</span>,right=<span class="number">0</span>;</span><br><span class="line">    <span class="keyword">int</span> matchCount=<span class="number">0</span>;</span><br><span class="line">    <span class="comment">//无脑套路滑窗</span></span><br><span class="line">    <span class="keyword">while</span>(right&lt;s.length())&#123;</span><br><span class="line">        <span class="keyword">char</span> c=s.charAt(right);</span><br><span class="line">        <span class="keyword">if</span>(need[c-<span class="string">&#x27;A&#x27;</span>]&gt;<span class="number">0</span>)&#123;</span><br><span class="line">            cur[c-<span class="string">&#x27;A&#x27;</span>]++;</span><br><span class="line">            <span class="keyword">if</span>(cur[c-<span class="string">&#x27;A&#x27;</span>]==need[c-<span class="string">&#x27;A&#x27;</span>])&#123;</span><br><span class="line">                matchCount++;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">while</span>(left&lt;=right &amp;&amp; matchCount==needCount)&#123;</span><br><span class="line">            res=Math.min(right-left+<span class="number">1</span>,res);</span><br><span class="line">            <span class="keyword">char</span> cl=s.charAt(left);</span><br><span class="line">            <span class="keyword">if</span>(need[cl-<span class="string">&#x27;A&#x27;</span>]&gt;<span class="number">0</span>)&#123;</span><br><span class="line">                cur[cl-<span class="string">&#x27;A&#x27;</span>]--;</span><br><span class="line">                <span class="keyword">if</span>(cur[cl-<span class="string">&#x27;A&#x27;</span>]&lt;need[cl-<span class="string">&#x27;A&#x27;</span>])&#123;</span><br><span class="line">                    matchCount--;</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">            left++;</span><br><span class="line">        &#125;</span><br><span class="line">        right++;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p><strong>解法二</strong></p>
<p>上面的解法是考虑<code>窗口内</code>的元素组成，窗口内至少应该有哪些元素，反过来想，我们窗口内的元素是多出来的元素，我们是把多的元素放到窗口中，那么窗口外的元素就肯定都是<code>小于等于N/4</code>的了，那么我们就可以利用这一点进行滑窗，统计符合条件的窗口的最小值，这样代码就会简洁很多</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">//code删掉了，之前的代码有点问题，最后的返回值有些情况过不去，lc的case太弱了，让我过了</span></span><br></pre></td></tr></table></figure>

<p><strong>UPDATE: (2020.5.4)</strong></p>
<p>按照先前的模板来分析下，这里要求的是最小的修改次数，很明显不能用<code>for-if</code>，所以采用<code>for-while</code>的结构，<code>for-while</code>最基本的结构就是外层枚举所有<code>right</code>，内层根据题目要求缩减<code>left</code>，但是这题left也需要控制边界，我这里用的是<code>left&lt;=right</code> 但是实际上这样会有一类case结果不对，比如”QWER”这样的，返回的结果是1，<del>我上面在最后做了特判</del>（上面的特判是错的，比如“QWEE”这样的就返回0），其实这里还可以修改下边界，改成<code>left&lt;N</code>，这样就没问题了，这样left就可以超过right达到right+1，这样对”QWER”就能得到正确的结果，并且根据题目信息当<code>left=right+1</code>之后<code>left</code>就不会再增加了，while条件就无法满足了，但是有的题目<code>left</code>是不用设置限制的，基本上都是在达到right+1之后就不会继续增加了</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">balancedString</span><span class="params">(String s)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">if</span>(s==<span class="keyword">null</span> || s.length()&lt;=<span class="number">0</span>)&#123;</span><br><span class="line">            <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">int</span> N=s.length();</span><br><span class="line">        <span class="keyword">int</span> left=<span class="number">0</span>;</span><br><span class="line">        <span class="keyword">int</span> res=N;</span><br><span class="line">        <span class="keyword">int</span>[] freq=<span class="keyword">new</span> <span class="keyword">int</span>[<span class="number">26</span>];</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;N;i++) &#123;</span><br><span class="line">            freq[s.charAt(i)-<span class="string">&#x27;A&#x27;</span>]++;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> right=<span class="number">0</span>;right&lt;N;right++)&#123;</span><br><span class="line">            freq[s.charAt(right)-<span class="string">&#x27;A&#x27;</span>]--;</span><br><span class="line">            <span class="keyword">while</span>(left&lt;N &amp;&amp; freq[<span class="string">&#x27;Q&#x27;</span>-<span class="string">&#x27;A&#x27;</span>]&lt;=N/<span class="number">4</span> &amp;&amp; freq[<span class="string">&#x27;W&#x27;</span>-<span class="string">&#x27;A&#x27;</span>]&lt;=N/<span class="number">4</span> &amp;&amp; freq[<span class="string">&#x27;E&#x27;</span>-<span class="string">&#x27;A&#x27;</span>]&lt;=N/<span class="number">4</span> &amp;&amp; freq[<span class="string">&#x27;R&#x27;</span>-<span class="string">&#x27;A&#x27;</span>]&lt;=N/<span class="number">4</span>)&#123;</span><br><span class="line">                res=Math.min(res,right-left+<span class="number">1</span>);</span><br><span class="line">                freq[s.charAt(left++)-<span class="string">&#x27;A&#x27;</span>]++;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="1358-包含所有三种字符的子字符串数目"><a href="#1358-包含所有三种字符的子字符串数目" class="headerlink" title="1358. 包含所有三种字符的子字符串数目"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/number-of-substrings-containing-all-three-characters/" >1358. 包含所有三种字符的子字符串数目<i class="fas fa-external-link-alt"></i></a></h2><p>给你一个字符串 s ，它只包含三种字符 a, b 和 c 。</p>
<p>请你返回 a，b 和 c 都 <strong>至少</strong> 出现过一次的子字符串数目。</p>
<p><strong>示例 1：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入：s = <span class="string">&quot;abcabc&quot;</span></span><br><span class="line">输出：<span class="number">10</span></span><br><span class="line">解释：包含 a，b 和 c 各至少一次的子字符串为 <span class="string">&quot;abc&quot;</span>, <span class="string">&quot;abca&quot;</span>, <span class="string">&quot;abcab&quot;</span>, <span class="string">&quot;abcabc&quot;</span>, <span class="string">&quot;bca&quot;</span>, <span class="string">&quot;bcab&quot;</span>, <span class="string">&quot;bcabc&quot;</span>, <span class="string">&quot;cab&quot;</span>, <span class="string">&quot;cabc&quot;</span> 和 <span class="string">&quot;abc&quot;</span> (相同字符串算多次)。</span><br></pre></td></tr></table></figure>

<p><strong>示例 2：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入：s = <span class="string">&quot;aaacb&quot;</span></span><br><span class="line">输出：<span class="number">3</span></span><br><span class="line">解释：包含 a，b 和 c 各至少一次的子字符串为 <span class="string">&quot;aaacb&quot;</span>, <span class="string">&quot;aacb&quot;</span> 和 <span class="string">&quot;acb&quot;</span> 。</span><br></pre></td></tr></table></figure>

<p><strong>示例 3：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入：s = <span class="string">&quot;abc&quot;</span></span><br><span class="line">输出：<span class="number">1</span></span><br></pre></td></tr></table></figure>

<p><strong>提示：</strong></p>
<ul>
<li>3 &lt;= s.length &lt;= 5 x 10^4</li>
<li>s 只包含字符 a，b 和 c 。</li>
</ul>
<p><strong>解法一</strong></p>
<p>20双周赛T3</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">numberOfSubstrings</span><span class="params">(String s)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">int</span>[] freq=<span class="keyword">new</span> <span class="keyword">int</span>[<span class="number">3</span>];</span><br><span class="line">    <span class="keyword">int</span> left=<span class="number">0</span>,right=-<span class="number">1</span>,slen=s.length();</span><br><span class="line">    <span class="keyword">int</span> res=<span class="number">0</span>;</span><br><span class="line">    <span class="comment">//abc</span></span><br><span class="line">    <span class="keyword">while</span>(left&lt;slen-<span class="number">2</span>)&#123;</span><br><span class="line">        <span class="keyword">while</span>(right+<span class="number">1</span>&lt;slen &amp;&amp; !valid(freq))&#123;</span><br><span class="line">            freq[s.charAt(++right)-<span class="string">&#x27;a&#x27;</span>]++;</span><br><span class="line">        &#125;</span><br><span class="line">        res+=valid(freq)?(slen-right):<span class="number">0</span>;</span><br><span class="line">        freq[s.charAt(left)-<span class="string">&#x27;a&#x27;</span>]--;</span><br><span class="line">        left++;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">valid</span><span class="params">(<span class="keyword">int</span>[] freq)</span></span>&#123;</span><br><span class="line">    <span class="keyword">return</span> freq[<span class="number">0</span>]!=<span class="number">0</span> &amp;&amp; freq[<span class="number">1</span>]!=<span class="number">0</span> &amp;&amp; freq[<span class="number">2</span>]!=<span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>枚举所有的左边界，然后找到最短的可以满足的右边界，那么包括右边界和之后的所有的都满足条件，直接计算就可以了，时间复杂度<code>O(N)</code></p>
<p><strong>解法二</strong></p>
<p>2020.5.4 用自己总结的滑窗模板重写，也是<code>for-while</code>结构，right和left不能同时扩展。比如<code>&quot;aaacb&quot;</code>这样的case</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">numberOfSubstrings</span><span class="params">(String s)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">int</span> left=<span class="number">0</span>;</span><br><span class="line">    <span class="keyword">int</span> res=<span class="number">0</span>;</span><br><span class="line">    <span class="keyword">int</span> n=s.length();</span><br><span class="line">    <span class="keyword">int</span>[] freq=<span class="keyword">new</span> <span class="keyword">int</span>[<span class="number">3</span>];</span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">int</span> right=<span class="number">0</span>;right&lt;n;right++)&#123;</span><br><span class="line">        freq[s.charAt(right)-<span class="string">&#x27;a&#x27;</span>]++;</span><br><span class="line">        <span class="keyword">while</span>(freq[<span class="number">0</span>]&gt;<span class="number">0</span> &amp;&amp; freq[<span class="number">1</span>]&gt;<span class="number">0</span> &amp;&amp; freq[<span class="number">2</span>]&gt;<span class="number">0</span>)&#123;</span><br><span class="line">            res+=n-right; <span class="comment">//后面的都符合条件</span></span><br><span class="line">            freq[s.charAt(left)-<span class="string">&#x27;a&#x27;</span>]--;</span><br><span class="line">            left++;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h2 id="1423-可获得的最大点数"><a href="#1423-可获得的最大点数" class="headerlink" title="1423. 可获得的最大点数"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/maximum-points-you-can-obtain-from-cards/" >1423. 可获得的最大点数<i class="fas fa-external-link-alt"></i></a></h2><p>几张卡牌 <strong>排成一行</strong>，每张卡牌都有一个对应的点数。点数由整数数组 <code>cardPoints</code> 给出。</p>
<p>每次行动，你可以从行的开头或者末尾拿一张卡牌，最终你必须正好拿 <code>k</code> 张卡牌。</p>
<p>你的点数就是你拿到手中的所有卡牌的点数之和。</p>
<p>给你一个整数数组 <code>cardPoints</code> 和整数 <code>k</code>，请你返回可以获得的最大点数。</p>
<p><strong>示例 1：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入：cardPoints = [<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>,<span class="number">5</span>,<span class="number">6</span>,<span class="number">1</span>], k = <span class="number">3</span></span><br><span class="line">输出：<span class="number">12</span></span><br><span class="line">解释：第一次行动，不管拿哪张牌，你的点数总是 <span class="number">1</span> 。但是，先拿最右边的卡牌将会最大化你的可获得点数。最优策略是拿右边的三张牌，最终点数为 <span class="number">1</span> + <span class="number">6</span> + <span class="number">5</span> = <span class="number">12</span> 。</span><br></pre></td></tr></table></figure>

<p><strong>示例 2：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入：cardPoints = [<span class="number">2</span>,<span class="number">2</span>,<span class="number">2</span>], k = <span class="number">2</span></span><br><span class="line">输出：<span class="number">4</span></span><br><span class="line">解释：无论你拿起哪两张卡牌，可获得的点数总是 <span class="number">4</span> 。</span><br></pre></td></tr></table></figure>

<p><strong>示例 3：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入：cardPoints = [<span class="number">9</span>,<span class="number">7</span>,<span class="number">7</span>,<span class="number">9</span>,<span class="number">7</span>,<span class="number">7</span>,<span class="number">9</span>], k = <span class="number">7</span></span><br><span class="line">输出：<span class="number">55</span></span><br><span class="line">解释：你必须拿起所有卡牌，可以获得的点数为所有卡牌的点数之和。</span><br></pre></td></tr></table></figure>

<p><strong>示例 4：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入：cardPoints = [<span class="number">1</span>,<span class="number">1000</span>,<span class="number">1</span>], k = <span class="number">1</span></span><br><span class="line">输出：<span class="number">1</span></span><br><span class="line">解释：你无法拿到中间那张卡牌，所以可以获得的最大点数为 <span class="number">1</span> 。 </span><br></pre></td></tr></table></figure>

<p><strong>示例 5：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入：cardPoints = [<span class="number">1</span>,<span class="number">79</span>,<span class="number">80</span>,<span class="number">1</span>,<span class="number">1</span>,<span class="number">1</span>,<span class="number">200</span>,<span class="number">1</span>], k = <span class="number">3</span></span><br><span class="line">输出：<span class="number">202</span></span><br></pre></td></tr></table></figure>

<p><strong>提示：</strong></p>
<ul>
<li><code>1 &lt;= cardPoints.length &lt;= 10^5</code></li>
<li><code>1 &lt;= cardPoints[i] &lt;= 10^4</code></li>
<li><code>1 &lt;= k &lt;= cardPoints.length</code></li>
</ul>
<p><strong>解法一</strong></p>
<p>186周赛T2，很明显的滑动窗口，前后拿K张最大，只需要求一个最小的<code>[n-k]</code>区间值就行了，也可以用前缀和，思路都一样</p>
<figure class="highlight go"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">maxScore</span><span class="params">(cardPoints []<span class="keyword">int</span>, k <span class="keyword">int</span>)</span> <span class="title">int</span></span> &#123;</span><br><span class="line">    <span class="keyword">if</span> cardPoints == <span class="literal">nil</span> || <span class="built_in">len</span>(cardPoints) == <span class="number">0</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="number">0</span></span><br><span class="line">    &#125;</span><br><span class="line">    n := <span class="built_in">len</span>(cardPoints)</span><br><span class="line">    left := <span class="number">0</span></span><br><span class="line">    right := n - k - <span class="number">1</span></span><br><span class="line">    sum := <span class="number">0</span></span><br><span class="line">    windowSum := <span class="number">0</span></span><br><span class="line">    <span class="keyword">for</span> i, num := <span class="keyword">range</span> cardPoints &#123;</span><br><span class="line">        sum += num</span><br><span class="line">        <span class="keyword">if</span> i == right &#123;</span><br><span class="line">            windowSum = sum</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span> k == n &#123;</span><br><span class="line">        <span class="keyword">return</span> sum</span><br><span class="line">    &#125;</span><br><span class="line">    minWin := windowSum</span><br><span class="line">    <span class="keyword">for</span> right+<span class="number">1</span> &lt; n &#123;</span><br><span class="line">        windowSum += (cardPoints[right+<span class="number">1</span>] - cardPoints[left])</span><br><span class="line">        minWin = min(windowSum, minWin)</span><br><span class="line">        right++</span><br><span class="line">        left++</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> sum - minWin</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">min</span><span class="params">(a, b <span class="keyword">int</span>)</span> <span class="title">int</span></span> &#123;</span><br><span class="line">    <span class="keyword">if</span> a &lt; b &#123;</span><br><span class="line">        <span class="keyword">return</span> a</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> b</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<p>Tag里面有dp，确实这题和前面的<a href="http://imlgw.top/2019/09/01/leetcode-dong-tai-gui-hua/#877-%E7%9F%B3%E5%AD%90%E6%B8%B8%E6%88%8F">石子游戏</a>有一点像，但是还是滑窗来的比较直接。。</p>
<h2 id="1208-尽可能使字符串相等"><a href="#1208-尽可能使字符串相等" class="headerlink" title="1208. 尽可能使字符串相等"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/get-equal-substrings-within-budget/" >1208. 尽可能使字符串相等<i class="fas fa-external-link-alt"></i></a></h2><p>给你两个长度相同的字符串，<code>s</code> 和 <code>t</code>。</p>
<p>将 <code>s</code> 中的第 <code>i</code> 个字符变到 <code>t</code> 中的第 <code>i</code> 个字符需要 <code>|s[i] - t[i]|</code> 的开销（开销可能为 0），也就是两个字符的 ASCII 码值的差的绝对值。</p>
<p>用于变更字符串的最大预算是 <code>maxCost</code>。在转化字符串时，总开销应当小于等于该预算，这也意味着字符串的转化可能是不完全的。</p>
<p>如果你可以将 <code>s</code> 的子字符串转化为它在 <code>t</code> 中对应的子字符串，则返回可以转化的最大长度。</p>
<p>如果 <code>s</code> 中没有子字符串可以转化成 <code>t</code> 中对应的子字符串，则返回 <code>0</code>。</p>
<p><strong>示例 1：</strong></p>
<figure class="highlight go"><table><tr><td class="code"><pre><span class="line">输入：s = <span class="string">&quot;abcd&quot;</span>, t = <span class="string">&quot;bcdf&quot;</span>, cost = <span class="number">3</span></span><br><span class="line">输出：<span class="number">3</span></span><br><span class="line">解释：s 中的 <span class="string">&quot;abc&quot;</span> 可以变为 <span class="string">&quot;bcd&quot;</span>。开销为 <span class="number">3</span>，所以最大长度为 <span class="number">3</span>。</span><br></pre></td></tr></table></figure>

<p><strong>示例 2：</strong></p>
<figure class="highlight go"><table><tr><td class="code"><pre><span class="line">输入：s = <span class="string">&quot;abcd&quot;</span>, t = <span class="string">&quot;cdef&quot;</span>, cost = <span class="number">3</span></span><br><span class="line">输出：<span class="number">1</span></span><br><span class="line">解释：s 中的任一字符要想变成 t 中对应的字符，其开销都是 <span class="number">2</span>。因此，最大长度为 <span class="number">1</span>。</span><br></pre></td></tr></table></figure>

<p><strong>示例 3：</strong></p>
<figure class="highlight go"><table><tr><td class="code"><pre><span class="line">输入：s = <span class="string">&quot;abcd&quot;</span>, t = <span class="string">&quot;acde&quot;</span>, cost = <span class="number">0</span></span><br><span class="line">输出：<span class="number">1</span></span><br><span class="line">解释：你无法作出任何改动，所以最大长度为 <span class="number">1</span>。</span><br></pre></td></tr></table></figure>

<p><strong>提示：</strong></p>
<ul>
<li><code>1 &lt;= s.length, t.length &lt;= 10^5</code></li>
<li><code>0 &lt;= maxCost &lt;= 10^6</code></li>
<li><code>s</code> 和 <code>t</code> 都只含小写英文字母。</li>
</ul>
<p><strong>解法一</strong></p>
<figure class="highlight go"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">equalSubstring</span><span class="params">(s <span class="keyword">string</span>, t <span class="keyword">string</span>, maxCost <span class="keyword">int</span>)</span> <span class="title">int</span></span> &#123;</span><br><span class="line">    left := <span class="number">0</span></span><br><span class="line">    cost := <span class="number">0</span></span><br><span class="line">    res := <span class="number">0</span></span><br><span class="line">    <span class="keyword">for</span> right := <span class="number">0</span>; right &lt; <span class="built_in">len</span>(s); right++ &#123;</span><br><span class="line">        cost += getCost(s[right], t[right])</span><br><span class="line">        <span class="keyword">if</span> cost &lt;= maxCost &#123;</span><br><span class="line">            res = max(res, right-left+<span class="number">1</span>)</span><br><span class="line">        &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">            cost -= getCost(s[left], t[left])</span><br><span class="line">            left++</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> res</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">getCost</span><span class="params">(a, b <span class="keyword">byte</span>)</span> <span class="title">int</span></span> &#123;</span><br><span class="line">    <span class="keyword">if</span> a &lt; b &#123; <span class="comment">//a-b&lt;0 byte是uint8直接这样减会变成正数</span></span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">int</span>(b - a)</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">int</span>(a - b)</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">max</span><span class="params">(a, b <span class="keyword">int</span>)</span> <span class="title">int</span></span> &#123;</span><br><span class="line">    <span class="keyword">if</span> a &gt; b &#123;</span><br><span class="line">        <span class="keyword">return</span> a</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> b</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>这个题本身不难，主要是为了学习滑窗类型的题，这题我又改了好长时间，果然做滑窗的题还是有点乱，不过做了这一题之后已经有点感觉了，目前打算把所有的滑窗都重做一遍，然后总结一下套路</p>
<p><strong>思考</strong></p>
<p>下面<code>for-while</code>的结构似乎更加统一，上面<code>for-if</code>的结构只能用在求<strong>最长，最大</strong>的情况下，这种时候<code>left</code>和<code>right</code>允许同时加加，所以用<code>if</code>也是可以的，但是求最短的时候，比如上面<a href="#209-%E9%95%BF%E5%BA%A6%E6%9C%80%E5%B0%8F%E7%9A%84%E5%AD%90%E6%95%B0%E7%BB%84">209. 长度最小的子数组</a>就不能用<code>for-if</code> ，当right到达边界的时候left可能还需要继续移动，所以不能用<code>if</code></p>
<figure class="highlight go"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">equalSubstring</span><span class="params">(s <span class="keyword">string</span>, t <span class="keyword">string</span>, maxCost <span class="keyword">int</span>)</span> <span class="title">int</span></span> &#123;</span><br><span class="line">    left := <span class="number">0</span></span><br><span class="line">    cost := <span class="number">0</span></span><br><span class="line">    res := <span class="number">0</span></span><br><span class="line">    <span class="keyword">for</span> right := <span class="number">0</span>; right &lt; <span class="built_in">len</span>(s); right++ &#123;</span><br><span class="line">        cost += getCost(s[right], t[right])</span><br><span class="line">        <span class="keyword">for</span> cost &gt; maxCost &#123;</span><br><span class="line">            cost -= getCost(s[left], t[left])</span><br><span class="line">            left++</span><br><span class="line">        &#125;</span><br><span class="line">        res = max(res, right-left+<span class="number">1</span>)</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> res</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="1052-爱生气的书店老板"><a href="#1052-爱生气的书店老板" class="headerlink" title="1052. 爱生气的书店老板"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/grumpy-bookstore-owner/" >1052. 爱生气的书店老板<i class="fas fa-external-link-alt"></i></a></h2><p>今天，书店老板有一家店打算试营业 <code>customers.length</code> 分钟。每分钟都有一些顾客（<code>customers[i]</code>）会进入书店，所有这些顾客都会在那一分钟结束后离开。</p>
<p>在某些时候，书店老板会生气。 如果书店老板在第 <code>i</code> 分钟生气，那么 <code>grumpy[i] = 1</code>，否则 <code>grumpy[i] = 0</code>。 当书店老板生气时，那一分钟的顾客就会不满意，不生气则他们是满意的。</p>
<p>书店老板知道一个秘密技巧，能抑制自己的情绪，可以让自己连续 <code>X</code> 分钟不生气，但却只能使用一次。</p>
<p>请你返回这一天营业下来，最多有多少客户能够感到满意的数量。</p>
<p><strong>示例：</strong></p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">输入：customers = [1,0,1,2,1,1,7,5], grumpy = [0,1,0,1,0,1,0,1], X = 3</span><br><span class="line">输出：16</span><br><span class="line">解释：</span><br><span class="line">书店老板在最后 3 分钟保持冷静。</span><br><span class="line">感到满意的最大客户数量 = 1 + 1 + 1 + 1 + 7 + 5 = 16.</span><br></pre></td></tr></table></figure>

<p><strong>提示：</strong></p>
<ul>
<li><code>1 &lt;= X &lt;= customers.length == grumpy.length &lt;= 20000</code></li>
<li><code>0 &lt;= customers[i] &lt;= 1000</code></li>
<li><code>0 &lt;= grumpy[i] &lt;= 1</code></li>
</ul>
<p><strong>解法一</strong></p>
<p>滑动窗口的感觉来了，越来越熟练了，这题直接bugfree了😁</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">maxSatisfied</span><span class="params">(<span class="keyword">int</span>[] customers, <span class="keyword">int</span>[] grumpy, <span class="keyword">int</span> X)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span>(grumpy==<span class="keyword">null</span> || grumpy.length&lt;<span class="number">0</span>) <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">int</span> N=grumpy.length;</span><br><span class="line">    <span class="keyword">int</span> left=<span class="number">0</span>;</span><br><span class="line">    <span class="keyword">int</span> window=<span class="number">0</span>;<span class="comment">//窗口内反转人数</span></span><br><span class="line">    <span class="keyword">int</span> max=<span class="number">0</span>; <span class="comment">//最多反转人数</span></span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">int</span> right=<span class="number">0</span>;right&lt;N;right++)&#123;</span><br><span class="line">        <span class="keyword">if</span>(grumpy[right]==<span class="number">1</span>)&#123;</span><br><span class="line">            window+=customers[right];</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="comment">//while和if都可以,个人比较喜欢while通用性比较强</span></span><br><span class="line">        <span class="keyword">while</span>(right-left+<span class="number">1</span>&gt;X)&#123;</span><br><span class="line">            <span class="keyword">if</span>(grumpy[left]==<span class="number">1</span>)&#123;</span><br><span class="line">                window-=customers[left];</span><br><span class="line">            &#125;</span><br><span class="line">            left++;</span><br><span class="line">        &#125;</span><br><span class="line">        max=Math.max(window,max);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">int</span> res=<span class="number">0</span>;</span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;N;i++)&#123;</span><br><span class="line">        res+=(grumpy[i]==<span class="number">0</span>?customers[i]:<span class="number">0</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> res+max;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>可以看到仍然是前面总结的<code>for-while</code>结构，等我把所有的滑窗tag做完了再来总结一波</p>
<h2 id="1040-移动石子直到连续-II"><a href="#1040-移动石子直到连续-II" class="headerlink" title="1040. 移动石子直到连续 II"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/moving-stones-until-consecutive-ii/" >1040. 移动石子直到连续 II<i class="fas fa-external-link-alt"></i></a></h2><p>在一个长度<strong>无限</strong>的数轴上，第 <code>i</code> 颗石子的位置为 <code>stones[i]</code>。如果一颗石子的位置最小/最大，那么该石子被称作<strong>端点石子</strong>。</p>
<p>每个回合，你可以将一颗端点石子拿起并移动到一个未占用的位置，使得该石子不再是一颗端点石子。</p>
<p>值得注意的是，如果石子像 <code>stones = [1,2,5]</code> 这样，你将<strong>无法</strong>移动位于位置 5 的端点石子，因为无论将它移动到任何位置（例如 0 或 3），该石子都仍然会是端点石子。</p>
<p>当你无法进行任何移动时，即，这些石子的位置连续时，游戏结束。</p>
<p>要使游戏结束，你可以执行的最小和最大移动次数分别是多少？ 以长度为 2 的数组形式返回答案：<code>answer = [minimum_moves, maximum_moves]</code> 。</p>
<p><strong>示例 1：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入：[<span class="number">7</span>,<span class="number">4</span>,<span class="number">9</span>]</span><br><span class="line">输出：[<span class="number">1</span>,<span class="number">2</span>]</span><br><span class="line">解释：</span><br><span class="line">我们可以移动一次，<span class="number">4</span> -&gt; <span class="number">8</span>，游戏结束。</span><br><span class="line">或者，我们可以移动两次 <span class="number">9</span> -&gt; <span class="number">5</span>，<span class="number">4</span> -&gt; <span class="number">6</span>，游戏结束。</span><br></pre></td></tr></table></figure>

<p><strong>示例 2：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入：[<span class="number">6</span>,<span class="number">5</span>,<span class="number">4</span>,<span class="number">3</span>,<span class="number">10</span>]</span><br><span class="line">输出：[<span class="number">2</span>,<span class="number">3</span>]</span><br><span class="line">解释：</span><br><span class="line">我们可以移动 <span class="number">3</span> -&gt; <span class="number">8</span>，接着是 <span class="number">10</span> -&gt; <span class="number">7</span>，游戏结束。</span><br><span class="line">或者，我们可以移动 <span class="number">3</span> -&gt; <span class="number">7</span>, <span class="number">4</span> -&gt; <span class="number">8</span>, <span class="number">5</span> -&gt; <span class="number">9</span>，游戏结束。</span><br><span class="line">注意，我们无法进行 <span class="number">10</span> -&gt; <span class="number">2</span> 这样的移动来结束游戏，因为这是不合要求的移动。</span><br></pre></td></tr></table></figure>

<p><strong>示例 3：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入：[<span class="number">100</span>,<span class="number">101</span>,<span class="number">104</span>,<span class="number">102</span>,<span class="number">103</span>]</span><br><span class="line">输出：[<span class="number">0</span>,<span class="number">0</span>]</span><br></pre></td></tr></table></figure>

<p><strong>提示：</strong></p>
<ol>
<li><code>3 &lt;= stones.length &lt;= 10^4</code></li>
<li><code>1 &lt;= stones[i] &lt;= 10^9</code></li>
<li><code>stones[i]</code> 的值各不相同。</li>
</ol>
<p><strong>解法一</strong></p>
<p>懵逼，某次周赛的T4，嗯抄，不会做，题目都差点没看懂</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">int</span>[] numMovesStonesII(<span class="keyword">int</span>[] stones) &#123;</span><br><span class="line">    <span class="keyword">if</span>(stones==<span class="keyword">null</span> || stones.length&lt;=<span class="number">0</span>)&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">new</span> <span class="keyword">int</span>[<span class="number">2</span>];</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">//0 1 2 3 4 5 6 7 8 9 10</span></span><br><span class="line">    <span class="comment">//      0 1 2 3        4</span></span><br><span class="line">    <span class="keyword">int</span> N=stones.length;</span><br><span class="line">    Arrays.sort(stones);</span><br><span class="line">    <span class="keyword">int</span> left=<span class="number">0</span>;</span><br><span class="line">    <span class="keyword">int</span>[] res=<span class="keyword">new</span> <span class="keyword">int</span>[<span class="number">2</span>];</span><br><span class="line">    res[<span class="number">0</span>]=Integer.MAX_VALUE;</span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">int</span> right=<span class="number">0</span>;right&lt;N;right++)&#123;</span><br><span class="line">        <span class="comment">//整个区间范围大于N了需要缩小区间</span></span><br><span class="line">        <span class="keyword">while</span>(stones[right]-stones[left]+<span class="number">1</span>&gt;N)&#123; </span><br><span class="line">            left++;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">int</span> windowStones=right-left+<span class="number">1</span>;</span><br><span class="line">        <span class="keyword">if</span>(windowStones==N-<span class="number">1</span>&amp;&amp;stones[right]-stones[left]+<span class="number">1</span>==N-<span class="number">1</span>)&#123;</span><br><span class="line">            res[<span class="number">0</span>]=Math.min(<span class="number">2</span>,res[<span class="number">0</span>]);</span><br><span class="line">        &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">            res[<span class="number">0</span>]=Math.min(res[<span class="number">0</span>],N-windowStones);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    res[<span class="number">1</span>]=Math.max(stones[N-<span class="number">1</span>]-stones[<span class="number">1</span>]-N+<span class="number">2</span>,stones[N-<span class="number">2</span>]-stones[<span class="number">0</span>]-N+<span class="number">2</span>);</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="1456-定长子串中元音的最大数目"><a href="#1456-定长子串中元音的最大数目" class="headerlink" title="1456. 定长子串中元音的最大数目"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/maximum-number-of-vowels-in-a-substring-of-given-length/" >1456. 定长子串中元音的最大数目<i class="fas fa-external-link-alt"></i></a></h2><p>给你字符串 s 和整数 k 。</p>
<p>请返回字符串 s 中长度为 k 的单个子字符串中可能包含的最大元音字母数。</p>
<p>英文中的 元音字母 为（a, e, i, o, u）。</p>
<p><strong>示例 1：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入：s = <span class="string">&quot;abciiidef&quot;</span>, k = <span class="number">3</span></span><br><span class="line">输出：<span class="number">3</span></span><br><span class="line">解释：子字符串 <span class="string">&quot;iii&quot;</span> 包含 <span class="number">3</span> 个元音字母。</span><br></pre></td></tr></table></figure>
<p><strong>示例 2：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入：s = <span class="string">&quot;aeiou&quot;</span>, k = <span class="number">2</span></span><br><span class="line">输出：<span class="number">2</span></span><br><span class="line">解释：任意长度为 <span class="number">2</span> 的子字符串都包含 <span class="number">2</span> 个元音字母。</span><br></pre></td></tr></table></figure>
<p><strong>示例 3：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入：s = <span class="string">&quot;leetcode&quot;</span>, k = <span class="number">3</span></span><br><span class="line">输出：<span class="number">2</span></span><br><span class="line">解释：<span class="string">&quot;lee&quot;</span>、<span class="string">&quot;eet&quot;</span> 和 <span class="string">&quot;ode&quot;</span> 都包含 <span class="number">2</span> 个元音字母。</span><br></pre></td></tr></table></figure>
<p><strong>示例 4：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入：s = <span class="string">&quot;rhythms&quot;</span>, k = <span class="number">4</span></span><br><span class="line">输出：<span class="number">0</span></span><br><span class="line">解释：字符串 s 中不含任何元音字母。</span><br></pre></td></tr></table></figure>
<p><strong>示例 5：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入：s = <span class="string">&quot;tryhard&quot;</span>, k = <span class="number">4</span></span><br><span class="line">输出：<span class="number">1</span></span><br></pre></td></tr></table></figure>

<p><strong>提示：</strong></p>
<ul>
<li>1 &lt;= s.length &lt;= 10^5</li>
<li>s 由小写英文字母组成</li>
<li>1 &lt;= k &lt;= s.length</li>
</ul>
<p><strong>解法一</strong></p>
<p>好久没写滑窗的题了，回顾下之前的模板，<code>for-while</code>结构</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">maxVowels</span><span class="params">(String s, <span class="keyword">int</span> k)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">int</span> left=<span class="number">0</span>;</span><br><span class="line">    <span class="keyword">int</span> res=<span class="number">0</span>;</span><br><span class="line">    <span class="keyword">int</span> count=<span class="number">0</span>;</span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">int</span> right=<span class="number">0</span>;right&lt;s.length();right++)&#123;</span><br><span class="line">        <span class="keyword">if</span>(vowel(s.charAt(right)))&#123;</span><br><span class="line">            count++;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">while</span>(right-left &gt;= k)&#123;</span><br><span class="line">            <span class="keyword">if</span>(vowel(s.charAt(left)))&#123;</span><br><span class="line">                count--;</span><br><span class="line">            &#125;</span><br><span class="line">            left++;</span><br><span class="line">        &#125;</span><br><span class="line">        res=Math.max(res,count);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">vowel</span><span class="params">(<span class="keyword">char</span> ch)</span></span>&#123;</span><br><span class="line">    <span class="keyword">return</span> ch==<span class="string">&#x27;a&#x27;</span> || ch==<span class="string">&#x27;e&#x27;</span> || ch==<span class="string">&#x27;i&#x27;</span> || ch==<span class="string">&#x27;o&#x27;</span> || ch==<span class="string">&#x27;u&#x27;</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<h2 id="1461-检查一个字符串是否包含所有长度为-K-的二进制子串"><a href="#1461-检查一个字符串是否包含所有长度为-K-的二进制子串" class="headerlink" title="1461. 检查一个字符串是否包含所有长度为 K 的二进制子串"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/check-if-a-string-contains-all-binary-codes-of-size-k/" >1461. 检查一个字符串是否包含所有长度为 K 的二进制子串<i class="fas fa-external-link-alt"></i></a></h2><p>Difficulty: <strong>中等</strong></p>
<p>给你一个二进制字符串 <code>s</code> 和一个整数 <code>k</code> 。</p>
<p>如果所有长度为 <code>k</code> 的二进制字符串都是 <code>s</code> 的子串，请返回 True ，否则请返回 False 。</p>
<p><strong>示例 1：</strong></p>
<figure class="highlight go"><table><tr><td class="code"><pre><span class="line">输入：s = <span class="string">&quot;00110110&quot;</span>, k = <span class="number">2</span></span><br><span class="line">输出：<span class="literal">true</span></span><br><span class="line">解释：长度为 <span class="number">2</span> 的二进制串包括 <span class="string">&quot;00&quot;</span>，<span class="string">&quot;01&quot;</span>，<span class="string">&quot;10&quot;</span> 和 <span class="string">&quot;11&quot;</span>。它们分别是 s 中下标为 <span class="number">0</span>，<span class="number">1</span>，<span class="number">3</span>，<span class="number">2</span> 开始的长度为 <span class="number">2</span> 的子串。</span><br></pre></td></tr></table></figure>

<p><strong>示例 2：</strong></p>
<figure class="highlight go"><table><tr><td class="code"><pre><span class="line">输入：s = <span class="string">&quot;00110&quot;</span>, k = <span class="number">2</span></span><br><span class="line">输出：<span class="literal">true</span></span><br></pre></td></tr></table></figure>

<p><strong>示例 3：</strong></p>
<figure class="highlight go"><table><tr><td class="code"><pre><span class="line">输入：s = <span class="string">&quot;0110&quot;</span>, k = <span class="number">1</span></span><br><span class="line">输出：<span class="literal">true</span></span><br><span class="line">解释：长度为 <span class="number">1</span> 的二进制串包括 <span class="string">&quot;0&quot;</span> 和 <span class="string">&quot;1&quot;</span>，显然它们都是 s 的子串。</span><br></pre></td></tr></table></figure>

<p><strong>示例 4：</strong></p>
<figure class="highlight go"><table><tr><td class="code"><pre><span class="line">输入：s = <span class="string">&quot;0110&quot;</span>, k = <span class="number">2</span></span><br><span class="line">输出：<span class="literal">false</span></span><br><span class="line">解释：长度为 <span class="number">2</span> 的二进制串 <span class="string">&quot;00&quot;</span> 没有出现在 s 中。</span><br></pre></td></tr></table></figure>

<p><strong>示例 5：</strong></p>
<figure class="highlight go"><table><tr><td class="code"><pre><span class="line">输入：s = <span class="string">&quot;0000000001011100&quot;</span>, k = <span class="number">4</span></span><br><span class="line">输出：<span class="literal">false</span></span><br></pre></td></tr></table></figure>

<p><strong>提示：</strong></p>
<ul>
<li>  <code>1 &lt;= s.length &lt;= 5 * 10^5</code></li>
<li>  <code>s</code> 中只含 0 和 1 。</li>
<li>  <code>1 &lt;= k &lt;= 20</code></li>
</ul>
<p><strong>解法一</strong></p>
<p>某次周赛的T2还是T3，忘了，我用了最暴力的方法，直接回溯生成了所有的二进制串，然后对比的，写的很快，也AC了，但是但是后面一直没时间重写，今天偶然发现了这道题，重写下</p>
<p>经典for-while结构</p>
<figure class="highlight golang"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">hasAllCodes</span><span class="params">(s <span class="keyword">string</span>, k <span class="keyword">int</span>)</span> <span class="title">bool</span></span> &#123;</span><br><span class="line">    <span class="keyword">var</span> set = <span class="built_in">make</span>(<span class="keyword">map</span>[<span class="keyword">int</span>]<span class="keyword">bool</span>)</span><br><span class="line">    <span class="keyword">var</span> left = <span class="number">0</span></span><br><span class="line">    <span class="keyword">var</span> cur = <span class="number">0</span></span><br><span class="line">    <span class="keyword">for</span> right := <span class="number">0</span>; right &lt; <span class="built_in">len</span>(s); right++&#123;</span><br><span class="line">        cur = cur * <span class="number">2</span> + <span class="keyword">int</span>(s[right] &amp; <span class="number">1</span>)</span><br><span class="line">        <span class="keyword">for</span> right - left + <span class="number">1</span> &gt; k&#123;</span><br><span class="line">            cur &amp;= ^(<span class="number">1</span> &lt;&lt; k) <span class="comment">//将首位置为0</span></span><br><span class="line">            left++</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span> right - left + <span class="number">1</span> == k&#123;</span><br><span class="line">            set[cur] = <span class="literal">true</span>   </span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="built_in">len</span>(set) == <span class="number">1</span> &lt;&lt; k</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>这个题也可以直接存字符串进去，但是存字符串的时间复杂度就不是O(N)了(N为字符长度)，而是O(KN)，因为字符串Hash的复杂度是O(K)，但是这里K很小，所以其实也无所谓，但是我们还是要追求更加优秀的解法，所以最好的做法还是将其转换成数字，然后存到哈希表中，这里看了别人的解法又学到了一手位运算的小技巧，<code>cur &amp; ^(1&lt;&lt;k)</code>（k为cur长度-1）可以将cur首位置为0，也就是消去首位，原理也很简单，就不赘述了</p>
<h2 id="1498-满足条件的子序列数目"><a href="#1498-满足条件的子序列数目" class="headerlink" title="1498. 满足条件的子序列数目"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/number-of-subsequences-that-satisfy-the-given-sum-condition/" >1498. 满足条件的子序列数目<i class="fas fa-external-link-alt"></i></a></h2><p>Difficulty: <strong>中等</strong></p>
<p>给你一个整数数组 <code>nums</code> 和一个整数 <code>target</code> 。</p>
<p>请你统计并返回 <code>nums</code> 中能满足其最小元素与最大元素的 <strong>和</strong> 小于或等于 <code>target</code> 的 <strong>非空</strong> 子序列的数目。</p>
<p>由于答案可能很大，请将结果对 10^9 + 7 取余后返回。</p>
<p><strong>示例 1：</strong></p>
<figure class="highlight go"><table><tr><td class="code"><pre><span class="line">输入：nums = [<span class="number">3</span>,<span class="number">5</span>,<span class="number">6</span>,<span class="number">7</span>], target = <span class="number">9</span></span><br><span class="line">输出：<span class="number">4</span></span><br><span class="line">解释：有 <span class="number">4</span> 个子序列满足该条件。</span><br><span class="line">[<span class="number">3</span>] -&gt; 最小元素 + 最大元素 &lt;= target (<span class="number">3</span> + <span class="number">3</span> &lt;= <span class="number">9</span>)</span><br><span class="line">[<span class="number">3</span>,<span class="number">5</span>] -&gt; (<span class="number">3</span> + <span class="number">5</span> &lt;= <span class="number">9</span>)</span><br><span class="line">[<span class="number">3</span>,<span class="number">5</span>,<span class="number">6</span>] -&gt; (<span class="number">3</span> + <span class="number">6</span> &lt;= <span class="number">9</span>)</span><br><span class="line">[<span class="number">3</span>,<span class="number">6</span>] -&gt; (<span class="number">3</span> + <span class="number">6</span> &lt;= <span class="number">9</span>)</span><br></pre></td></tr></table></figure>

<p><strong>示例 2：</strong></p>
<figure class="highlight go"><table><tr><td class="code"><pre><span class="line">输入：nums = [<span class="number">3</span>,<span class="number">3</span>,<span class="number">6</span>,<span class="number">8</span>], target = <span class="number">10</span></span><br><span class="line">输出：<span class="number">6</span></span><br><span class="line">解释：有 <span class="number">6</span> 个子序列满足该条件。（nums 中可以有重复数字）</span><br><span class="line">[<span class="number">3</span>] , [<span class="number">3</span>] , [<span class="number">3</span>,<span class="number">3</span>], [<span class="number">3</span>,<span class="number">6</span>] , [<span class="number">3</span>,<span class="number">6</span>] , [<span class="number">3</span>,<span class="number">3</span>,<span class="number">6</span>]</span><br></pre></td></tr></table></figure>

<p><strong>示例 3：</strong></p>
<figure class="highlight go"><table><tr><td class="code"><pre><span class="line">输入：nums = [<span class="number">2</span>,<span class="number">3</span>,<span class="number">3</span>,<span class="number">4</span>,<span class="number">6</span>,<span class="number">7</span>], target = <span class="number">12</span></span><br><span class="line">输出：<span class="number">61</span></span><br><span class="line">解释：共有 <span class="number">63</span> 个非空子序列，其中 <span class="number">2</span> 个不满足条件（[<span class="number">6</span>,<span class="number">7</span>], [<span class="number">7</span>]）</span><br><span class="line">有效序列总数为（<span class="number">63</span> - <span class="number">2</span> = <span class="number">61</span>）</span><br></pre></td></tr></table></figure>

<p><strong>示例 4：</strong></p>
<figure class="highlight go"><table><tr><td class="code"><pre><span class="line">输入：nums = [<span class="number">5</span>,<span class="number">2</span>,<span class="number">4</span>,<span class="number">1</span>,<span class="number">7</span>,<span class="number">6</span>,<span class="number">8</span>], target = <span class="number">16</span></span><br><span class="line">输出：<span class="number">127</span></span><br><span class="line">解释：所有非空子序列都满足条件 (<span class="number">2</span>^<span class="number">7</span> - <span class="number">1</span>) = <span class="number">127</span></span><br></pre></td></tr></table></figure>

<p><strong>提示：</strong></p>
<ul>
<li>  <code>1 &lt;= nums.length &lt;= 10^5</code></li>
<li>  <code>1 &lt;= nums[i] &lt;= 10^6</code></li>
<li>  <code>1 &lt;= target &lt;= 10^6</code></li>
</ul>
<p><strong>解法一</strong></p>
<p>双指针滑窗，很关键的一步就是排序，因为我们只关心最大最小值，而且是子序列，与顺序无关</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">//双指针</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">numSubseq</span><span class="params">(<span class="keyword">int</span>[] nums, <span class="keyword">int</span> target)</span> </span>&#123;</span><br><span class="line">    Arrays.sort(nums);</span><br><span class="line">    <span class="keyword">int</span> MOD = (<span class="keyword">int</span>)(<span class="number">1e9</span>+<span class="number">7</span>);</span><br><span class="line">    <span class="keyword">int</span> n = nums.length;</span><br><span class="line">    <span class="comment">//预处理出幂值表</span></span><br><span class="line">    <span class="keyword">int</span>[] pow = <span class="keyword">new</span> <span class="keyword">int</span>[n];</span><br><span class="line">    pow[<span class="number">0</span>] = <span class="number">1</span>;</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">1</span>; i &lt; n; i++)&#123;</span><br><span class="line">        pow[i] = (pow[i-<span class="number">1</span>] &lt;&lt; <span class="number">1</span>) % MOD;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">int</span> left = <span class="number">0</span>, right = n-<span class="number">1</span>;</span><br><span class="line">    <span class="keyword">long</span> count = <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">while</span>(left &lt;= right)&#123;</span><br><span class="line">        <span class="keyword">while</span>(left &lt;= right &amp;&amp; nums[left] + nums[right] &gt; target) &#123;</span><br><span class="line">            right--;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span> (left &lt;= right) &#123;</span><br><span class="line">            <span class="comment">//nums[left] + nums[right] &lt;&gt;= target </span></span><br><span class="line">            <span class="comment">//包含left的子序列个数: left固定，在[left+1,right]选若干个，就有 2^(right-left) 种选法</span></span><br><span class="line">            count = (count + pow[right-left]) % MOD ;</span><br><span class="line">        &#125;</span><br><span class="line">        left++;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> (<span class="keyword">int</span>)count%MOD;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p><strong>解法二</strong></p>
<p>二分</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">//二分</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">numSubseq</span><span class="params">(<span class="keyword">int</span>[] nums, <span class="keyword">int</span> target)</span> </span>&#123;</span><br><span class="line">    Arrays.sort(nums);</span><br><span class="line">    <span class="keyword">int</span> MOD = (<span class="keyword">int</span>)(<span class="number">1e9</span>+<span class="number">7</span>);</span><br><span class="line">    <span class="keyword">int</span> n = nums.length;</span><br><span class="line">    <span class="comment">//预处理出幂值表</span></span><br><span class="line">    <span class="keyword">int</span>[] pow = <span class="keyword">new</span> <span class="keyword">int</span>[n];</span><br><span class="line">    pow[<span class="number">0</span>] = <span class="number">1</span>;</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">1</span>; i &lt; n; i++)&#123;</span><br><span class="line">        pow[i] = (pow[i-<span class="number">1</span>] &lt;&lt; <span class="number">1</span>) % MOD;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">long</span> count = <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; n; i++) &#123;</span><br><span class="line">        <span class="keyword">if</span> (target-nums[i] &lt; <span class="number">0</span>)&#123;</span><br><span class="line">            <span class="keyword">break</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">int</span> right = search(nums, target-nums[i]);</span><br><span class="line">        <span class="keyword">if</span> (right &gt;= i)&#123;</span><br><span class="line">            count = (count + pow[right-i]) % MOD;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> (<span class="keyword">int</span>) count % MOD;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//搜索最后一个小于等于target的值</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">search</span><span class="params">(<span class="keyword">int</span>[] nums, <span class="keyword">int</span> target)</span></span>&#123;</span><br><span class="line">    <span class="keyword">int</span> left = <span class="number">0</span>, right = nums.length-<span class="number">1</span>;</span><br><span class="line">    <span class="keyword">int</span> res = -<span class="number">1</span>;</span><br><span class="line">    <span class="keyword">while</span> (left &lt;= right) &#123;</span><br><span class="line">        <span class="keyword">int</span> mid = left + (right-left)/<span class="number">2</span>;</span><br><span class="line">        <span class="keyword">if</span> (nums[mid] &lt;= target)&#123;</span><br><span class="line">            res = mid;</span><br><span class="line">            left = mid + <span class="number">1</span>;</span><br><span class="line">        &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">            right = mid - <span class="number">1</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h2 id="904-水果成篮"><a href="#904-水果成篮" class="headerlink" title="904. 水果成篮"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/fruit-into-baskets/" >904. 水果成篮<i class="fas fa-external-link-alt"></i></a></h2><p>Difficulty: <strong>中等</strong></p>
<p>在一排树中，第 <code>i</code> 棵树产生 <code>tree[i]</code> 型的水果。<br>你可以<strong>从你选择的任何树开始</strong>，然后重复执行以下步骤：</p>
<ol>
<li> 把这棵树上的水果放进你的篮子里。如果你做不到，就停下来。</li>
<li> 移动到当前树右侧的下一棵树。如果右边没有树，就停下来。</li>
</ol>
<p>请注意，在选择一颗树后，你没有任何选择：你必须执行步骤 1，然后执行步骤 2，然后返回步骤 1，然后执行步骤 2，依此类推，直至停止。</p>
<p>你有两个篮子，每个篮子可以携带任何数量的水果，但你希望每个篮子只携带一种类型的水果。<br>用这个程序你能收集的水果总量是多少？</p>
<blockquote>
<p>感觉这里想表达的应该是水果树的数量<br><strong>示例 1：</strong></p>
</blockquote>
<figure class="highlight go"><table><tr><td class="code"><pre><span class="line">输入：[<span class="number">1</span>,<span class="number">2</span>,<span class="number">1</span>]</span><br><span class="line">输出：<span class="number">3</span></span><br><span class="line">解释：我们可以收集 [<span class="number">1</span>,<span class="number">2</span>,<span class="number">1</span>]。</span><br></pre></td></tr></table></figure>

<p><strong>示例 2：</strong></p>
<figure class="highlight go"><table><tr><td class="code"><pre><span class="line">输入：[<span class="number">0</span>,<span class="number">1</span>,<span class="number">2</span>,<span class="number">2</span>]</span><br><span class="line">输出：<span class="number">3</span></span><br><span class="line">解释：我们可以收集 [<span class="number">1</span>,<span class="number">2</span>,<span class="number">2</span>].</span><br><span class="line">如果我们从第一棵树开始，我们将只能收集到 [<span class="number">0</span>, <span class="number">1</span>]。</span><br></pre></td></tr></table></figure>

<p><strong>示例 3：</strong></p>
<figure class="highlight go"><table><tr><td class="code"><pre><span class="line">输入：[<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">2</span>,<span class="number">2</span>]</span><br><span class="line">输出：<span class="number">4</span></span><br><span class="line">解释：我们可以收集 [<span class="number">2</span>,<span class="number">3</span>,<span class="number">2</span>,<span class="number">2</span>].</span><br><span class="line">如果我们从第一棵树开始，我们将只能收集到 [<span class="number">1</span>, <span class="number">2</span>]。</span><br></pre></td></tr></table></figure>

<p><strong>示例 4：</strong></p>
<figure class="highlight go"><table><tr><td class="code"><pre><span class="line">输入：[<span class="number">3</span>,<span class="number">3</span>,<span class="number">3</span>,<span class="number">1</span>,<span class="number">2</span>,<span class="number">1</span>,<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">3</span>,<span class="number">4</span>]</span><br><span class="line">输出：<span class="number">5</span></span><br><span class="line">解释：我们可以收集 [<span class="number">1</span>,<span class="number">2</span>,<span class="number">1</span>,<span class="number">1</span>,<span class="number">2</span>].</span><br><span class="line">如果我们从第一棵树或第八棵树开始，我们将只能收集到 <span class="number">4</span> 个水果。</span><br></pre></td></tr></table></figure>

<p><strong>提示：</strong></p>
<ol>
<li> <code>1 &lt;= tree.length &lt;= 40000</code></li>
<li> <code>0 &lt;= tree[i] &lt; tree.length</code></li>
</ol>
<p><strong>解法一</strong></p>
<p>题目意思其实就是求只包含2个元素的最长子串，题目表述的不太清楚，已经反馈了</p>
<figure class="highlight golang"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">totalFruit</span><span class="params">(tree []<span class="keyword">int</span>)</span> <span class="title">int</span></span> &#123;</span><br><span class="line">    <span class="keyword">var</span> left = <span class="number">0</span></span><br><span class="line">    <span class="keyword">var</span> Max = <span class="function"><span class="keyword">func</span> <span class="params">(a, b <span class="keyword">int</span>)</span> <span class="title">int</span></span> &#123;<span class="keyword">if</span> a&gt;b &#123;<span class="keyword">return</span> a&#125;;<span class="keyword">return</span> b&#125;</span><br><span class="line">    <span class="keyword">var</span> n = <span class="built_in">len</span>(tree)</span><br><span class="line">    <span class="keyword">var</span> freq [<span class="number">40001</span>]<span class="keyword">int</span></span><br><span class="line">    <span class="keyword">var</span> res, count = <span class="number">0</span>, <span class="number">0</span></span><br><span class="line">    <span class="keyword">for</span> right := <span class="number">0</span>; right &lt; n; right++ &#123;</span><br><span class="line">        <span class="keyword">if</span> freq[tree[right]] == <span class="number">0</span> &#123;</span><br><span class="line">            count++</span><br><span class="line">        &#125;</span><br><span class="line">        freq[tree[right]]++</span><br><span class="line">        <span class="keyword">for</span> count &gt; <span class="number">2</span> &#123;</span><br><span class="line">            freq[tree[left]]--</span><br><span class="line">            <span class="keyword">if</span> freq[tree[left]] == <span class="number">0</span> &#123;</span><br><span class="line">                count--</span><br><span class="line">            &#125;</span><br><span class="line">            left++</span><br><span class="line">        &#125;</span><br><span class="line">        res = Max(res, right-left+<span class="number">1</span>)</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> res</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h2 id="NC562-牛牛的魔法卡"><a href="#NC562-牛牛的魔法卡" class="headerlink" title="NC562.牛牛的魔法卡"></a><a class="link"   target="_blank" rel="noopener" href="https://www.nowcoder.com/practice/9b6fe52a68904c77aa81502f57ceac86" >NC562.牛牛的魔法卡<i class="fas fa-external-link-alt"></i></a></h2><p>牛牛从小就有收集魔法卡的习惯，他最大的愿望就是能够集齐 k 种不同种类的魔法卡，现在有 n 张魔法卡，这 n 张魔法卡存在于一维坐标点上，<br>每张魔法卡可能属于某一种类。牛牛如果想收集魔法卡就需要从当前坐标点跳跃到另外一个魔法卡所在的坐标点，花费的代价是两个跳跃坐标点之间的距离差。<br>牛牛可以从任意的坐标点出发，牛牛想知道他集齐 k 种魔法卡所花费的最小代价是多少，如果集不齐 k 种魔法卡，输出-1。<br>第一行输入两个整数 n,k, 分别表示魔法卡的个数和种类个数。<br>接下来有n行，每行两个数x，y 分别表示属于哪一种魔法卡和魔法卡所在的坐标</p>
<p><strong>示例1</strong></p>
<figure class="highlight go"><table><tr><td class="code"><pre><span class="line">输入: <span class="number">7</span>,<span class="number">3</span>,[[<span class="number">0</span>,<span class="number">1</span>],[<span class="number">0</span>,<span class="number">2</span>],[<span class="number">1</span>,<span class="number">5</span>],[<span class="number">1</span>,<span class="number">1</span>],[<span class="number">0</span>,<span class="number">7</span>],[<span class="number">2</span>,<span class="number">8</span>],[<span class="number">1</span>,<span class="number">3</span>]]</span><br><span class="line">输出: <span class="number">3</span></span><br><span class="line">说明: </span><br><span class="line">样例一：牛牛从坐标点<span class="number">5</span>出发，经过<span class="number">7</span>、<span class="number">8</span>两个点就收集了<span class="number">3</span>张不同种类的魔法卡，达成成就。所需代价 （<span class="number">7</span><span class="number">-5</span>）+（<span class="number">8</span><span class="number">-7</span>） = <span class="number">3</span></span><br></pre></td></tr></table></figure>
<p><strong>备注:</strong></p>
<ul>
<li>1&lt;=n&lt;=10^6</li>
<li>1&lt;=k&lt;=50 0&lt;=x&lt;k</li>
<li>0 &lt;= y &lt;= 1e9</li>
</ul>
<p><strong>解法一</strong></p>
<p>tag是二分，但是想了一会儿感觉好像没啥好的二分的思路，二分答案貌似可行，不过这题滑窗的思路更简单，类似<a href="#76-%E6%9C%80%E5%B0%8F%E8%A6%86%E7%9B%96%E5%AD%90%E4%B8%B2">76-最小覆盖子串</a>滑就完事儿了</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">solve</span> <span class="params">(<span class="keyword">int</span> n, <span class="keyword">int</span> k, <span class="keyword">int</span>[][] card)</span> </span>&#123;</span><br><span class="line">    <span class="comment">// write code here</span></span><br><span class="line">    Arrays.sort(card, (c1,c2)-&gt;c1[<span class="number">1</span>]-c2[<span class="number">1</span>]);</span><br><span class="line">    <span class="keyword">int</span> INF = Integer.MAX_VALUE;</span><br><span class="line">    <span class="keyword">int</span> left = <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">int</span> count = <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">int</span>[] freq = <span class="keyword">new</span> <span class="keyword">int</span>[k+<span class="number">1</span>];</span><br><span class="line">    <span class="keyword">int</span> res = INF;</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> right = <span class="number">0</span>; right &lt; n; right++) &#123;</span><br><span class="line">        <span class="keyword">if</span> (freq[card[right][<span class="number">0</span>]] == <span class="number">0</span>) &#123;</span><br><span class="line">            count++;</span><br><span class="line">        &#125;</span><br><span class="line">        freq[card[right][<span class="number">0</span>]]++;</span><br><span class="line">        <span class="keyword">while</span>(left&lt;=right &amp;&amp; count == k)&#123;</span><br><span class="line">            res = Math.min(res, card[right][<span class="number">1</span>] - card[left][<span class="number">1</span>]);</span><br><span class="line">            freq[card[left][<span class="number">0</span>]]--;</span><br><span class="line">            <span class="keyword">if</span> (freq[card[left][<span class="number">0</span>]]==<span class="number">0</span>) &#123;</span><br><span class="line">                count--;</span><br><span class="line">            &#125;</span><br><span class="line">            left++;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span> (res == INF) &#123;</span><br><span class="line">        <span class="keyword">return</span> -<span class="number">1</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h2 id="1870-全零子串的数量（LintCode）"><a href="#1870-全零子串的数量（LintCode）" class="headerlink" title="1870. 全零子串的数量（LintCode）"></a><a class="link"   target="_blank" rel="noopener" href="https://www.lintcode.com/problem/number-of-substrings-with-all-zeroes/description" >1870. 全零子串的数量（LintCode）<i class="fas fa-external-link-alt"></i></a></h2><p>给出一个只包含0或1的字符串str,请返回这个字符串中全为0的子字符串的个数 1&lt;=|str|&lt;=30000</p>
<p><strong>例1:</strong></p>
<figure class="highlight go"><table><tr><td class="code"><pre><span class="line">输入:<span class="string">&quot;00010011&quot;</span></span><br><span class="line">输出:<span class="number">9</span></span><br><span class="line">解释:</span><br><span class="line"><span class="string">&quot;0&quot;</span>子字符串有<span class="number">5</span>个,</span><br><span class="line"><span class="string">&quot;00&quot;</span>子字符串有<span class="number">3</span>个,</span><br><span class="line"><span class="string">&quot;000&quot;</span>子字符串有<span class="number">1</span>个。</span><br><span class="line">所以返回<span class="number">9</span></span><br></pre></td></tr></table></figure>
<p><strong>例2:</strong></p>
<figure class="highlight go"><table><tr><td class="code"><pre><span class="line">输入:<span class="string">&quot;010010&quot;</span></span><br><span class="line">输出:<span class="number">5</span></span><br></pre></td></tr></table></figure>
<p><strong>解法一</strong></p>
<p>直接滑就行了，统计所有0区间的长度，注意组合数的计算就行了</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">// 1 1 1 1 1 (5+4+3+2+1) = n(n-1)/2 + n or n(n+1)/2</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">stringCount</span><span class="params">(String str)</span> </span>&#123;</span><br><span class="line">    <span class="comment">// Write your code here.</span></span><br><span class="line">    <span class="keyword">int</span> left = <span class="number">0</span>, right = <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">int</span> res = <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">while</span> (right &lt; str.length()) &#123;</span><br><span class="line">        <span class="keyword">while</span>(right &lt; str.length() &amp;&amp; str.charAt(right) == <span class="string">&#x27;0&#x27;</span>)&#123;</span><br><span class="line">            right++;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="comment">// (0  0  0) 1 1</span></span><br><span class="line">        <span class="comment">//  l  n     r</span></span><br><span class="line">        <span class="keyword">int</span> n = right-left;</span><br><span class="line">        <span class="comment">//C(n+1,2)/2</span></span><br><span class="line">        res += n*(n+<span class="number">1</span>)/<span class="number">2</span>;</span><br><span class="line">        right++;</span><br><span class="line">        left = right;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="1529-绝对差不超过限制的三元子数组（LintCode）"><a href="#1529-绝对差不超过限制的三元子数组（LintCode）" class="headerlink" title="1529. 绝对差不超过限制的三元子数组（LintCode）"></a><a class="link"   target="_blank" rel="noopener" href="https://www.lintcode.com/problem/triplet-subarray-with-absolute-diff-less-than-or-equal-to-limit/description" >1529. 绝对差不超过限制的三元子数组（LintCode<i class="fas fa-external-link-alt"></i></a>）</h2><p>给定一个递增的整数数组nums，和一个表示限制的整数limit，请你返回满足条件的三元子数组的个数，使得该子数组中的任意两个元素之间的绝对差小于或者等于limit。</p>
<p>如果不存在满足条件的子数组，则返回 0 。</p>
<p><strong>数据范围：</strong> 1 ≤ len(nums) ≤ 1e4，1 ≤ limit ≤ 1e6，0 ≤ nums[i] ≤ 1e6<br>由于答案可能很大，请返回它对99997867取余后的结果。</p>
<p><strong>样例 1:</strong></p>
<figure class="highlight go"><table><tr><td class="code"><pre><span class="line">输入：[<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>], <span class="number">3</span></span><br><span class="line">输出：<span class="number">4</span></span><br><span class="line">解释：可选方案有(<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>), (<span class="number">1</span>, <span class="number">2</span>, <span class="number">4</span>), (<span class="number">1</span>, <span class="number">3</span>, <span class="number">4</span>), (<span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>)。因此，满足条件的三元组有<span class="number">4</span>个。</span><br></pre></td></tr></table></figure>

<p><strong>样例 2:</strong></p>
<figure class="highlight go"><table><tr><td class="code"><pre><span class="line">输入：[<span class="number">1</span>, <span class="number">10</span>, <span class="number">20</span>, <span class="number">30</span>, <span class="number">50</span>], <span class="number">19</span></span><br><span class="line">输出：<span class="number">1</span></span><br><span class="line">解释：唯一可行的三元组是(<span class="number">1</span>, <span class="number">10</span>, <span class="number">20</span>)，所以答案为<span class="number">1</span>。</span><br></pre></td></tr></table></figure>
<p><strong>挑战</strong><br>你可以只用O(n)的时间复杂度解决这个问题吗？</p>
<p><strong>解法一</strong></p>
<p>我一开始看见是Hard想的挺复杂的，什么单调栈都搞出来了，但是仔细看题会发现题目给的数组是有序的，所以直接滑窗然后统计就行了，这里需要注意计算的方式，避免算重</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">//LintCode上居然是Hard，感觉不是很难</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">tripletSubarray</span><span class="params">(<span class="keyword">int</span>[] nums, <span class="keyword">int</span> limit)</span> </span>&#123;</span><br><span class="line">    <span class="comment">// write your code here</span></span><br><span class="line">    <span class="keyword">int</span> n = nums.length;</span><br><span class="line">    <span class="keyword">int</span> left = <span class="number">0</span>, right = <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">int</span> res = <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">while</span> (left &lt;= right) &#123;</span><br><span class="line">        <span class="comment">//找到最远的合法right</span></span><br><span class="line">        <span class="keyword">while</span> (right &lt; n &amp;&amp; nums[right]-nums[left] &lt;= limit) &#123;</span><br><span class="line">            right++;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="comment">//  1  (2 3 4)  5</span></span><br><span class="line">        <span class="comment">//left   len  right</span></span><br><span class="line">        <span class="keyword">int</span> len = right-left-<span class="number">1</span>;</span><br><span class="line">        left++;</span><br><span class="line">        <span class="keyword">if</span> (len &lt; <span class="number">2</span>) <span class="keyword">continue</span>;</span><br><span class="line">        <span class="comment">//C(len,2) 求以left开头，包含left的所有3元组，这样不会重复</span></span><br><span class="line">        res += len*(len-<span class="number">1</span>)/<span class="number">2</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<blockquote>
<p>感觉自己静下心来想的话很多题目还是可以自己做出来的，但是就是想的可能有点慢，特别是竞赛中，规定了时间后一慌就更慢了。。看来还是练少了</p>
</blockquote>
<h2 id="1375-至少K个不同字符的子串（LintCode）"><a href="#1375-至少K个不同字符的子串（LintCode）" class="headerlink" title="1375. 至少K个不同字符的子串（LintCode）"></a><a class="link"   target="_blank" rel="noopener" href="https://www.lintcode.com/problem/substring-with-at-least-k-distinct-characters/description" >1375. 至少K个不同字符的子串（LintCode）<i class="fas fa-external-link-alt"></i></a></h2><p>给定一个仅包含小写字母的字符串 S.</p>
<p>返回 S 中至少包含 k 个不同字符的子串的数量.</p>
<ul>
<li>10 ≤ length(S) ≤ 1,000,000</li>
<li>1 ≤ k ≤ 26</li>
</ul>
<p><strong>样例 1:</strong></p>
<figure class="highlight go"><table><tr><td class="code"><pre><span class="line">输入: S = <span class="string">&quot;abcabcabca&quot;</span>, k = <span class="number">4</span></span><br><span class="line">输出: <span class="number">0</span></span><br><span class="line">解释: 字符串中一共就只有 <span class="number">3</span> 个不同的字符.</span><br></pre></td></tr></table></figure>
<p><strong>样例 2:</strong></p>
<figure class="highlight go"><table><tr><td class="code"><pre><span class="line">输入: S = <span class="string">&quot;abcabcabcabc&quot;</span>, k = <span class="number">3</span></span><br><span class="line">输出: <span class="number">55</span></span><br><span class="line">解释: 任意长度不小于 <span class="number">3</span> 的子串都含有 a, b, c 这三个字符.</span><br><span class="line">    比如,长度为 <span class="number">3</span> 的子串共有 <span class="number">10</span> 个, <span class="string">&quot;abc&quot;</span>, <span class="string">&quot;bca&quot;</span>, <span class="string">&quot;cab&quot;</span> ... <span class="string">&quot;abc&quot;</span></span><br><span class="line">    长度为 <span class="number">4</span> 的子串共有 <span class="number">9</span> 个, <span class="string">&quot;abca&quot;</span>, <span class="string">&quot;bcab&quot;</span>, <span class="string">&quot;cabc&quot;</span> ... <span class="string">&quot;cabc&quot;</span></span><br><span class="line">    ...</span><br><span class="line">    长度为 <span class="number">12</span> 的子串有 <span class="number">1</span> 个, 就是 S 本身.</span><br><span class="line">    所以答案是 <span class="number">1</span> + <span class="number">2</span> + ... + <span class="number">10</span> = <span class="number">55.</span></span><br></pre></td></tr></table></figure>

<p><strong>解法一</strong></p>
<p>经典滑窗，非常套路，想好怎么统计就行了</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">long</span> <span class="title">kDistinctCharacters</span><span class="params">(String s, <span class="keyword">int</span> k)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">int</span> n = s.length();</span><br><span class="line">    <span class="keyword">int</span> left = <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">int</span>[] freq = <span class="keyword">new</span> <span class="keyword">int</span>[<span class="number">128</span>];</span><br><span class="line">    <span class="keyword">int</span> count = <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">long</span> res = <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> right = <span class="number">0</span>; right &lt; n; right++) &#123;</span><br><span class="line">        <span class="keyword">char</span> cr = s.charAt(right);</span><br><span class="line">        <span class="keyword">if</span> (freq[cr] == <span class="number">0</span>) &#123;</span><br><span class="line">            count++;</span><br><span class="line">        &#125;</span><br><span class="line">        freq[cr]++;</span><br><span class="line">        <span class="keyword">while</span> (count &gt;= k &amp;&amp; left &lt;= right) &#123;</span><br><span class="line">            <span class="comment">// abc | abcabcabc</span></span><br><span class="line">            <span class="comment">// l r(2)          n(12)</span></span><br><span class="line">            <span class="comment">//统计以s[left,right]开头的所有子串</span></span><br><span class="line">            <span class="comment">//10+9+8+7+...+1</span></span><br><span class="line">            res += n-right;</span><br><span class="line">            <span class="keyword">char</span> cl = s.charAt(left);</span><br><span class="line">            freq[cl]--;</span><br><span class="line">            <span class="keyword">if</span> (freq[cl] &lt;= <span class="number">0</span>) &#123;</span><br><span class="line">                count--;</span><br><span class="line">            &#125;</span><br><span class="line">            left++;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="386-最多有k个不同字符的最长子字符串-LintCode"><a href="#386-最多有k个不同字符的最长子字符串-LintCode" class="headerlink" title="386. 最多有k个不同字符的最长子字符串(LintCode)"></a><a class="link"   target="_blank" rel="noopener" href="https://www.lintcode.com/problem/longest-substring-with-at-most-k-distinct-characters/description" >386. 最多有k个不同字符的最长子字符串(LintCode)<i class="fas fa-external-link-alt"></i></a></h2><p>给定字符串S，找到最多有k个不同字符的最长子串T。</p>
<p><strong>样例 1:</strong></p>
<figure class="highlight go"><table><tr><td class="code"><pre><span class="line">输入: S = <span class="string">&quot;eceba&quot;</span> 并且 k = <span class="number">3</span></span><br><span class="line">输出: <span class="number">4</span></span><br><span class="line">解释: T = <span class="string">&quot;eceb&quot;</span></span><br></pre></td></tr></table></figure>
<p><strong>样例 2:</strong></p>
<figure class="highlight go"><table><tr><td class="code"><pre><span class="line">输入: S = <span class="string">&quot;WORLD&quot;</span> 并且 k = <span class="number">4</span></span><br><span class="line">输出: <span class="number">4</span></span><br><span class="line">解释: T = <span class="string">&quot;WORL&quot;</span> 或 <span class="string">&quot;ORLD&quot;</span></span><br></pre></td></tr></table></figure>
<p><strong>挑战</strong>： O(n) 时间复杂度</p>
<p><strong>解法一</strong></p>
<p>无脑滑窗就行了，太套路了</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">lengthOfLongestSubstringKDistinct</span><span class="params">(String s, <span class="keyword">int</span> k)</span> </span>&#123;</span><br><span class="line">    <span class="comment">// write your code here</span></span><br><span class="line">    <span class="keyword">int</span> n = s.length();</span><br><span class="line">    <span class="keyword">int</span> left = <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">int</span> res = <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">int</span>[] freq = <span class="keyword">new</span> <span class="keyword">int</span>[<span class="number">128</span>];</span><br><span class="line">    <span class="keyword">int</span> count = <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> right = <span class="number">0</span>; right &lt; n; right++) &#123;</span><br><span class="line">        <span class="keyword">char</span> cr = s.charAt(right);</span><br><span class="line">        <span class="keyword">if</span> (freq[cr] == <span class="number">0</span>) &#123;</span><br><span class="line">            count++;</span><br><span class="line">        &#125;</span><br><span class="line">        freq[cr]++;</span><br><span class="line">        <span class="keyword">while</span> (left &lt;= right &amp;&amp; count &gt; k) &#123;</span><br><span class="line">            <span class="keyword">char</span> cl = s.charAt(left);</span><br><span class="line">            freq[cl]--;</span><br><span class="line">            <span class="keyword">if</span> (freq[cl] &lt;= <span class="number">0</span>) &#123;</span><br><span class="line">                count--;</span><br><span class="line">            &#125;</span><br><span class="line">            left++;</span><br><span class="line">        &#125;</span><br><span class="line">        res = Math.max(res, right-left+<span class="number">1</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h2 id="1675-数组的最小偏移量"><a href="#1675-数组的最小偏移量" class="headerlink" title="1675. 数组的最小偏移量"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/minimize-deviation-in-array/" >1675. 数组的最小偏移量<i class="fas fa-external-link-alt"></i></a></h2><p>Difficulty: <strong>困难</strong></p>
<p>给你一个由 <code>n</code> 个正整数组成的数组 <code>nums</code> 。</p>
<p>你可以对数组的任意元素执行任意次数的两类操作：</p>
<ul>
<li>如果元素是偶数 ，除以 <code>2</code><ul>
<li>  例如，如果数组是 <code>[1,2,3,4]</code> ，那么你可以对最后一个元素执行此操作，使其变成 <code>[1,2,3,2]</code></li>
</ul>
</li>
<li>如果元素是奇数 ，乘上 <code>2</code><ul>
<li>  例如，如果数组是 <code>[1,2,3,4]</code> ，那么你可以对第一个元素执行此操作，使其变成 <code>[2,2,3,4]</code></li>
</ul>
</li>
</ul>
<p>数组的 <strong>偏移量</strong> 是数组中任意两个元素之间的 <strong>最大差值</strong> 。</p>
<p>返回数组在执行某些操作之后可以拥有的 <strong>最小偏移量</strong> 。</p>
<p><strong>示例 1：</strong></p>
<figure class="highlight c"><table><tr><td class="code"><pre><span class="line">输入：nums = [<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>]</span><br><span class="line">输出：<span class="number">1</span></span><br><span class="line">解释：你可以将数组转换为 [<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">2</span>]，然后转换成 [<span class="number">2</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">2</span>]，偏移量是 <span class="number">3</span> - <span class="number">2</span> = <span class="number">1</span></span><br></pre></td></tr></table></figure>

<p><strong>示例 2：</strong></p>
<figure class="highlight c"><table><tr><td class="code"><pre><span class="line">输入：nums = [<span class="number">4</span>,<span class="number">1</span>,<span class="number">5</span>,<span class="number">20</span>,<span class="number">3</span>]</span><br><span class="line">输出：<span class="number">3</span></span><br><span class="line">解释：两次操作后，你可以将数组转换为 [<span class="number">4</span>,<span class="number">2</span>,<span class="number">5</span>,<span class="number">5</span>,<span class="number">3</span>]，偏移量是 <span class="number">5</span> - <span class="number">2</span> = <span class="number">3</span></span><br></pre></td></tr></table></figure>

<p><strong>示例 3：</strong></p>
<figure class="highlight c"><table><tr><td class="code"><pre><span class="line">输入：nums = [<span class="number">2</span>,<span class="number">10</span>,<span class="number">8</span>]</span><br><span class="line">输出：<span class="number">3</span></span><br></pre></td></tr></table></figure>

<p><strong>提示：</strong></p>
<ul>
<li>  n == nums.length</li>
<li>  2 &lt;= n &lt;= 10<sup><span style="display: inline;">5</span></sup></li>
<li>  1 &lt;= nums[i] &lt;= 10<sup>9</sup></li>
</ul>
<p><strong>解法一</strong></p>
<p>和上面<a href="#632-%E6%9C%80%E5%B0%8F%E5%8C%BA%E9%97%B4">632-最小区间</a>一样，将数据变成和最小区间一样的形式，然后直接套用</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">minimumDeviation</span><span class="params">(<span class="keyword">int</span>[] nums)</span> </span>&#123;</span><br><span class="line">    PriorityQueue&lt;<span class="keyword">int</span>[]&gt; pq = <span class="keyword">new</span> PriorityQueue&lt;&gt;((a, b)-&gt;a[<span class="number">2</span>]-b[<span class="number">2</span>]);</span><br><span class="line">    List&lt;List&lt;Integer&gt;&gt; lis = <span class="keyword">new</span> ArrayList&lt;&gt;();</span><br><span class="line">    <span class="keyword">int</span> max = <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; nums.length; i++) &#123;</span><br><span class="line">        ArrayList&lt;Integer&gt; tmp = <span class="keyword">new</span> ArrayList&lt;&gt;();</span><br><span class="line">        <span class="keyword">if</span> (nums[i] % <span class="number">2</span> == <span class="number">1</span>) &#123;</span><br><span class="line">            pq.add(<span class="keyword">new</span> <span class="keyword">int</span>[]&#123;i, <span class="number">0</span>, nums[i]&#125;);</span><br><span class="line">            max = Math.max(max, nums[i]);</span><br><span class="line">            tmp.add(nums[i]);</span><br><span class="line">            tmp.add(nums[i] * <span class="number">2</span>);</span><br><span class="line">        &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">            tmp.add(nums[i]);</span><br><span class="line">            <span class="keyword">while</span> (nums[i] % <span class="number">2</span> == <span class="number">0</span>) &#123;</span><br><span class="line">                tmp.add(nums[i]/<span class="number">2</span>);</span><br><span class="line">                nums[i]/=<span class="number">2</span>;</span><br><span class="line">            &#125;</span><br><span class="line">            pq.add(<span class="keyword">new</span> <span class="keyword">int</span>[]&#123;i, <span class="number">0</span>, nums[i]&#125;);</span><br><span class="line">            max = Math.max(max, nums[i]);</span><br><span class="line">            Collections.reverse(tmp);</span><br><span class="line">        &#125;</span><br><span class="line">        lis.add(tmp);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">int</span> res = Integer.MAX_VALUE;</span><br><span class="line">    <span class="keyword">while</span> (<span class="keyword">true</span>) &#123;</span><br><span class="line">        <span class="keyword">int</span>[] min = pq.poll();</span><br><span class="line">        res = Math.min(res, max-min[<span class="number">2</span>]);</span><br><span class="line">        <span class="keyword">if</span> (min[<span class="number">1</span>]+<span class="number">1</span> &gt;= lis.get(min[<span class="number">0</span>]).size()) &#123;</span><br><span class="line">            <span class="keyword">break</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">int</span> next = lis.get(min[<span class="number">0</span>]).get(min[<span class="number">1</span>]+<span class="number">1</span>);</span><br><span class="line">        pq.add(<span class="keyword">new</span> <span class="keyword">int</span>[]&#123;min[<span class="number">0</span>], min[<span class="number">1</span>]+<span class="number">1</span>, next&#125;);</span><br><span class="line">        max = Math.max(max, next);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p><strong>解法二</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">minimumDeviation2</span><span class="params">(<span class="keyword">int</span>[] nums)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">int</span> INF = <span class="number">0x3f3f3f3f</span>;</span><br><span class="line">    PriorityQueue&lt;Integer&gt; pq = <span class="keyword">new</span> PriorityQueue&lt;&gt;((a, b)-&gt;b-a);</span><br><span class="line">    <span class="keyword">int</span> min = INF;</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; nums.length; i++) &#123;</span><br><span class="line">        <span class="keyword">if</span> ((nums[i] &amp; <span class="number">1</span>) == <span class="number">1</span>) &#123;</span><br><span class="line">            nums[i] &lt;&lt;= <span class="number">1</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        min = Math.min(min, nums[i]);</span><br><span class="line">        pq.add(nums[i]);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">int</span> res = INF;</span><br><span class="line">    <span class="keyword">while</span> (<span class="keyword">true</span>) &#123;</span><br><span class="line">        <span class="keyword">int</span> max = pq.poll();</span><br><span class="line">        res = Math.min(res, max-min);</span><br><span class="line">        <span class="keyword">if</span> ((max&amp;<span class="number">1</span>)==<span class="number">1</span>) &#123;</span><br><span class="line">            <span class="keyword">break</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        pq.add(max/<span class="number">2</span>);</span><br><span class="line">        min = Math.min(min, max/<span class="number">2</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
        </div>

        
            <div class="post-copyright-info">
                <div class="article-copyright-info-container">
    <ul>
        <li>本文标题：LeetCode滑动窗口</li>
        <li>本文作者：Resolmi</li>
        <li>创建时间：2019-07-20 00:00:00</li>
        <li>
            本文链接：https://imlgw.top/2019/07/20/41e491de/
        </li>
        <li>
            版权声明：本博客所有文章除特别声明外，均采用 <a class="license" target="_blank" rel="noopener" href="https://creativecommons.org/licenses/by-nc-sa/4.0/deed.zh">BY-NC-SA</a> 许可协议。转载请注明出处！
        </li>
    </ul>
</div>

            </div>
        

        
            <div class="article-nav">
                
                    <div class="article-prev">
                        <a class="prev"
                           rel="prev"
                           href="/2019/07/24/7187a079/"
                        >
                            <span class="left arrow-icon flex-center">
                              <i class="fas fa-chevron-left"></i>
                            </span>
                            <span class="title flex-center">
                                <span class="post-nav-title-item">JUC并发工具包</span>
                                <span class="post-nav-item">上一篇</span>
                            </span>
                        </a>
                    </div>
                
                
                    <div class="article-next">
                        <a class="next"
                           rel="next"
                           href="/2019/07/19/df38ad26/"
                        >
                            <span class="title flex-center">
                                <span class="post-nav-title-item">Socket网络编程</span>
                                <span class="post-nav-item">下一篇</span>
                            </span>
                            <span class="right arrow-icon flex-center">
                              <i class="fas fa-chevron-right"></i>
                            </span>
                        </a>
                    </div>
                
            </div>
        

        
            <div class="comment-container">
                <div class="comments-container">
    <div id="comment-anchor"></div>
    <div class="comment-area-title">
        <i class="fas fa-comments">&nbsp;评论</i>
    </div>
    

        
            <section class="disqus-comments">
<div id="disqus_thread">
  <noscript>Please enable JavaScript to view the <a target="_blank" rel="noopener" href="//disqus.com/?ref_noscript">comments powered by Disqus.</a></noscript>
</div>
</section>

<script>
var disqus_shortname = 'imlgw';

var disqus_url = 'https://imlgw.top/2019/07/20/41e491de/';

(function(){
  var dsq = document.createElement('script');
  dsq.type = 'text/javascript';
  dsq.async = true;
  dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js';
  (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
})();
</script>

<script id="dsq-count-scr" src="//imlgw.disqus.com/count.js" async></script>
        
    
</div>

            </div>
        
    </div>
</div>


                
            </div>

        </div>

        <div class="page-main-content-bottom">
            <footer class="footer">
    <div class="info-container">
        <div class="copyright-info info-item">
            &copy;
            
              <span>2018</span>&nbsp;-&nbsp;
            
            2021&nbsp;<i class="fas fa-heart icon-animate"></i>&nbsp;<a href="/">Resolmi</a>
        </div>
        
            <script async data-pjax src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script>
            <div class="website-count info-item">
                
                    <span id="busuanzi_container_site_uv">
                        访问人数&nbsp;<span id="busuanzi_value_site_uv"></span>&ensp;
                    </span>
                
                
                    <span id="busuanzi_container_site_pv">
                        总访问量&nbsp;<span id="busuanzi_value_site_pv"></span>
                    </span>
                
            </div>
        
        
            <div class="icp-info info-item"><a target="_blank" rel="nofollow" href="https://beian.miit.gov.cn">鄂ICP备18011208号</a></div>
        
    </div>
</footer>

        </div>
    </div>

    
        <div class="post-tools">
            <div class="post-tools-container">
    <ul class="tools-list">
        <!-- TOC aside toggle -->
        
            <li class="tools-item page-aside-toggle">
                <i class="fas fa-outdent"></i>
            </li>
        

        <!-- go comment -->
        
            <li class="go-comment">
                <i class="fas fa-comment"></i>
            </li>
        
    </ul>
</div>

        </div>
    

    <div class="right-bottom-side-tools">
        <div class="side-tools-container">
    <ul class="side-tools-list">
        <li class="tools-item tool-font-adjust-plus flex-center">
            <i class="fas fa-search-plus"></i>
        </li>

        <li class="tools-item tool-font-adjust-minus flex-center">
            <i class="fas fa-search-minus"></i>
        </li>

        <li class="tools-item tool-expand-width flex-center">
            <i class="fas fa-arrows-alt-h"></i>
        </li>

        <li class="tools-item tool-dark-light-toggle flex-center">
            <i class="fas fa-moon"></i>
        </li>

        <!-- rss -->
        

        

        <li class="tools-item tool-scroll-to-bottom flex-center">
            <i class="fas fa-arrow-down"></i>
        </li>
    </ul>

    <ul class="exposed-tools-list">
        <li class="tools-item tool-toggle-show flex-center">
            <i class="fas fa-cog fa-spin"></i>
        </li>
        
            <li class="tools-item tool-scroll-to-top flex-center">
                <i class="arrow-up fas fa-arrow-up"></i>
                <span class="percent"></span>
            </li>
        
    </ul>
</div>

    </div>

    
        <aside class="page-aside">
            <div class="post-toc-wrap">
    <div class="post-toc">
        <ol class="nav"><li class="nav-item nav-level-2"><a class="nav-link" href="#LeetCode-%E6%BB%91%E5%8A%A8%E7%AA%97%E5%8F%A3"><span class="nav-number">1.</span> <span class="nav-text">LeetCode 滑动窗口</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#239-%E6%BB%91%E5%8A%A8%E7%AA%97%E5%8F%A3%E6%9C%80%E5%A4%A7%E5%80%BC"><span class="nav-number">2.</span> <span class="nav-text">239. 滑动窗口最大值</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#5312-%E5%A4%A7%E5%B0%8F%E4%B8%BA-K-%E4%B8%94%E5%B9%B3%E5%9D%87%E5%80%BC%E5%A4%A7%E4%BA%8E%E7%AD%89%E4%BA%8E%E9%98%88%E5%80%BC%E7%9A%84%E5%AD%90%E6%95%B0%E7%BB%84%E6%95%B0%E7%9B%AE"><span class="nav-number">3.</span> <span class="nav-text">5312. 大小为 K 且平均值大于等于阈值的子数组数目</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#3-%E6%97%A0%E9%87%8D%E5%A4%8D%E5%AD%97%E7%AC%A6%E7%9A%84%E6%9C%80%E9%95%BF%E5%AD%90%E4%B8%B2"><span class="nav-number">4.</span> <span class="nav-text">3. 无重复字符的最长子串</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#219-%E5%AD%98%E5%9C%A8%E9%87%8D%E5%A4%8D%E5%85%83%E7%B4%A0-II"><span class="nav-number">5.</span> <span class="nav-text">219. 存在重复元素 II</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#209-%E9%95%BF%E5%BA%A6%E6%9C%80%E5%B0%8F%E7%9A%84%E5%AD%90%E6%95%B0%E7%BB%84"><span class="nav-number">6.</span> <span class="nav-text">209. 长度最小的子数组</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E9%9D%A2%E8%AF%95%E9%A2%9857-II-%E5%92%8C%E4%B8%BAs%E7%9A%84%E8%BF%9E%E7%BB%AD%E6%AD%A3%E6%95%B0%E5%BA%8F%E5%88%97"><span class="nav-number">7.</span> <span class="nav-text">面试题57 - II. 和为s的连续正数序列</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#480-%E6%BB%91%E5%8A%A8%E7%AA%97%E5%8F%A3%E4%B8%AD%E4%BD%8D%E6%95%B0"><span class="nav-number">8.</span> <span class="nav-text">480. 滑动窗口中位数</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#76-%E6%9C%80%E5%B0%8F%E8%A6%86%E7%9B%96%E5%AD%90%E4%B8%B2"><span class="nav-number">9.</span> <span class="nav-text">76. 最小覆盖子串</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#632-%E6%9C%80%E5%B0%8F%E5%8C%BA%E9%97%B4"><span class="nav-number">10.</span> <span class="nav-text">632. 最小区间</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#438-%E6%89%BE%E5%88%B0%E5%AD%97%E7%AC%A6%E4%B8%B2%E4%B8%AD%E6%89%80%E6%9C%89%E5%AD%97%E6%AF%8D%E5%BC%82%E4%BD%8D%E8%AF%8D"><span class="nav-number">11.</span> <span class="nav-text">438. 找到字符串中所有字母异位词</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#567-%E5%AD%97%E7%AC%A6%E4%B8%B2%E7%9A%84%E6%8E%92%E5%88%97"><span class="nav-number">12.</span> <span class="nav-text">567. 字符串的排列</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E9%9D%A2%E8%AF%95%E9%A2%98-17-18-%E6%9C%80%E7%9F%AD%E8%B6%85%E4%B8%B2"><span class="nav-number">13.</span> <span class="nav-text">面试题 17.18. 最短超串</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#1004-%E6%9C%80%E5%A4%A7%E8%BF%9E%E7%BB%AD1%E7%9A%84%E4%B8%AA%E6%95%B0-III"><span class="nav-number">14.</span> <span class="nav-text">1004. 最大连续1的个数 III</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#5434-%E5%88%A0%E6%8E%89%E4%B8%80%E4%B8%AA%E5%85%83%E7%B4%A0%E4%BB%A5%E5%90%8E%E5%85%A8%E4%B8%BA-1-%E7%9A%84%E6%9C%80%E9%95%BF%E5%AD%90%E6%95%B0%E7%BB%84"><span class="nav-number">15.</span> <span class="nav-text">5434. 删掉一个元素以后全为 1 的最长子数组</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#424-%E6%9B%BF%E6%8D%A2%E5%90%8E%E7%9A%84%E6%9C%80%E9%95%BF%E9%87%8D%E5%A4%8D%E5%AD%97%E7%AC%A6"><span class="nav-number">16.</span> <span class="nav-text">424. 替换后的最长重复字符</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#1234-%E6%9B%BF%E6%8D%A2%E5%AD%90%E4%B8%B2%E5%BE%97%E5%88%B0%E5%B9%B3%E8%A1%A1%E5%AD%97%E7%AC%A6%E4%B8%B2"><span class="nav-number">17.</span> <span class="nav-text">1234. 替换子串得到平衡字符串</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#1358-%E5%8C%85%E5%90%AB%E6%89%80%E6%9C%89%E4%B8%89%E7%A7%8D%E5%AD%97%E7%AC%A6%E7%9A%84%E5%AD%90%E5%AD%97%E7%AC%A6%E4%B8%B2%E6%95%B0%E7%9B%AE"><span class="nav-number">18.</span> <span class="nav-text">1358. 包含所有三种字符的子字符串数目</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#1423-%E5%8F%AF%E8%8E%B7%E5%BE%97%E7%9A%84%E6%9C%80%E5%A4%A7%E7%82%B9%E6%95%B0"><span class="nav-number">19.</span> <span class="nav-text">1423. 可获得的最大点数</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#1208-%E5%B0%BD%E5%8F%AF%E8%83%BD%E4%BD%BF%E5%AD%97%E7%AC%A6%E4%B8%B2%E7%9B%B8%E7%AD%89"><span class="nav-number">20.</span> <span class="nav-text">1208. 尽可能使字符串相等</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#1052-%E7%88%B1%E7%94%9F%E6%B0%94%E7%9A%84%E4%B9%A6%E5%BA%97%E8%80%81%E6%9D%BF"><span class="nav-number">21.</span> <span class="nav-text">1052. 爱生气的书店老板</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#1040-%E7%A7%BB%E5%8A%A8%E7%9F%B3%E5%AD%90%E7%9B%B4%E5%88%B0%E8%BF%9E%E7%BB%AD-II"><span class="nav-number">22.</span> <span class="nav-text">1040. 移动石子直到连续 II</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#1456-%E5%AE%9A%E9%95%BF%E5%AD%90%E4%B8%B2%E4%B8%AD%E5%85%83%E9%9F%B3%E7%9A%84%E6%9C%80%E5%A4%A7%E6%95%B0%E7%9B%AE"><span class="nav-number">23.</span> <span class="nav-text">1456. 定长子串中元音的最大数目</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#1461-%E6%A3%80%E6%9F%A5%E4%B8%80%E4%B8%AA%E5%AD%97%E7%AC%A6%E4%B8%B2%E6%98%AF%E5%90%A6%E5%8C%85%E5%90%AB%E6%89%80%E6%9C%89%E9%95%BF%E5%BA%A6%E4%B8%BA-K-%E7%9A%84%E4%BA%8C%E8%BF%9B%E5%88%B6%E5%AD%90%E4%B8%B2"><span class="nav-number">24.</span> <span class="nav-text">1461. 检查一个字符串是否包含所有长度为 K 的二进制子串</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#1498-%E6%BB%A1%E8%B6%B3%E6%9D%A1%E4%BB%B6%E7%9A%84%E5%AD%90%E5%BA%8F%E5%88%97%E6%95%B0%E7%9B%AE"><span class="nav-number">25.</span> <span class="nav-text">1498. 满足条件的子序列数目</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#904-%E6%B0%B4%E6%9E%9C%E6%88%90%E7%AF%AE"><span class="nav-number">26.</span> <span class="nav-text">904. 水果成篮</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#NC562-%E7%89%9B%E7%89%9B%E7%9A%84%E9%AD%94%E6%B3%95%E5%8D%A1"><span class="nav-number">27.</span> <span class="nav-text">NC562.牛牛的魔法卡</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#1870-%E5%85%A8%E9%9B%B6%E5%AD%90%E4%B8%B2%E7%9A%84%E6%95%B0%E9%87%8F%EF%BC%88LintCode%EF%BC%89"><span class="nav-number">28.</span> <span class="nav-text">1870. 全零子串的数量（LintCode）</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#1529-%E7%BB%9D%E5%AF%B9%E5%B7%AE%E4%B8%8D%E8%B6%85%E8%BF%87%E9%99%90%E5%88%B6%E7%9A%84%E4%B8%89%E5%85%83%E5%AD%90%E6%95%B0%E7%BB%84%EF%BC%88LintCode%EF%BC%89"><span class="nav-number">29.</span> <span class="nav-text">1529. 绝对差不超过限制的三元子数组（LintCode）</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#1375-%E8%87%B3%E5%B0%91K%E4%B8%AA%E4%B8%8D%E5%90%8C%E5%AD%97%E7%AC%A6%E7%9A%84%E5%AD%90%E4%B8%B2%EF%BC%88LintCode%EF%BC%89"><span class="nav-number">30.</span> <span class="nav-text">1375. 至少K个不同字符的子串（LintCode）</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#386-%E6%9C%80%E5%A4%9A%E6%9C%89k%E4%B8%AA%E4%B8%8D%E5%90%8C%E5%AD%97%E7%AC%A6%E7%9A%84%E6%9C%80%E9%95%BF%E5%AD%90%E5%AD%97%E7%AC%A6%E4%B8%B2-LintCode"><span class="nav-number">31.</span> <span class="nav-text">386. 最多有k个不同字符的最长子字符串(LintCode)</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#1675-%E6%95%B0%E7%BB%84%E7%9A%84%E6%9C%80%E5%B0%8F%E5%81%8F%E7%A7%BB%E9%87%8F"><span class="nav-number">32.</span> <span class="nav-text">1675. 数组的最小偏移量</span></a></li></ol>
    </div>
</div>
        </aside>
    

    <div class="image-viewer-container">
    <img src="">
</div>


    
        <div class="search-pop-overlay">
    <div class="popup search-popup">
        <div class="search-header">
          <span class="search-input-field-pre">
            <i class="fas fa-keyboard"></i>
          </span>
            <div class="search-input-container">
                <input autocomplete="off"
                       autocorrect="off"
                       autocapitalize="off"
                       placeholder="搜索..."
                       spellcheck="false"
                       type="search"
                       class="search-input"
                >
            </div>
            <span class="popup-btn-close">
                <i class="fas fa-times"></i>
            </span>
        </div>
        <div id="search-result">
            <div id="no-result">
                <i class="fas fa-spinner fa-pulse fa-5x fa-fw"></i>
            </div>
        </div>
    </div>
</div>

    

</main>



<script src="//cdn.jsdelivr.net/npm/hexo-theme-keep@3.4.3/source/js/utils.js"></script><script src="//cdn.jsdelivr.net/npm/hexo-theme-keep@3.4.3/source/js/main.js"></script><script src="//cdn.jsdelivr.net/npm/hexo-theme-keep@3.4.3/source/js/header-shrink.js"></script><script src="//cdn.jsdelivr.net/npm/hexo-theme-keep@3.4.3/source/js/back2top.js"></script><script src="//cdn.jsdelivr.net/npm/hexo-theme-keep@3.4.3/source/js/dark-light-toggle.js"></script>


    <script src="//cdn.jsdelivr.net/npm/hexo-theme-keep@3.4.3/source/js/local-search.js"></script>



    <script src="//cdn.jsdelivr.net/npm/hexo-theme-keep@3.4.3/source/js/code-copy.js"></script>



    <script src="//cdn.jsdelivr.net/npm/hexo-theme-keep@3.4.3/source/js/lazyload.js"></script>


<div class="post-scripts pjax">
    
        <script src="//cdn.jsdelivr.net/npm/hexo-theme-keep@3.4.3/source/js/left-side-toggle.js"></script><script src="//cdn.jsdelivr.net/npm/hexo-theme-keep@3.4.3/source/js/libs/anime.min.js"></script><script src="//cdn.jsdelivr.net/npm/hexo-theme-keep@3.4.3/source/js/toc.js"></script>
    
</div>


    <script src="//cdn.jsdelivr.net/npm/hexo-theme-keep@3.4.3/source/js/libs/pjax.min.js"></script>
<script>
    window.addEventListener('DOMContentLoaded', () => {
        window.pjax = new Pjax({
            selectors: [
                'head title',
                '.page-container',
                '.pjax'
            ],
            history: true,
            debug: false,
            cacheBust: false,
            timeout: 0,
            analytics: false,
            currentUrlFullReload: false,
            scrollRestoration: false,
            // scrollTo: true,
        });

        document.addEventListener('pjax:send', () => {
            KEEP.utils.pjaxProgressBarStart();
        });

        document.addEventListener('pjax:complete', () => {
            KEEP.utils.pjaxProgressBarEnd();
            window.pjax.executeScripts(document.querySelectorAll('script[data-pjax], .pjax script'));
            KEEP.refresh();
        });
    });
</script>



<script src="https://cdn.jsdelivr.net/npm/live2d-widget@3.x/lib/L2Dwidget.min.js"></script><script>L2Dwidget.init({"pluginRootPath":"live2dw/","pluginJsPath":"lib/","pluginModelPath":"assets/","tagMode":false,"debug":false,"model":{"jsonPath":"https://cdn.jsdelivr.net/npm/live2d-widget-model-hijiki@1.0.5/assets/hijiki.model.json"},"display":{"superSample":2,"width":160,"height":320,"position":"right","hOffset":0,"vOffset":-70},"mobile":{"show":false,"scale":0.2},"log":false});</script></body>
</html>
